views:

3583

answers:

7

OK, so Sybase (12.5.4) will let me do the following to DROP a table if it already exists:

IF EXISTS (
    SELECT 1
    FROM sysobjects
    WHERE name = 'a_table'
    AND type = 'U'
)
DROP TABLE a_table
GO

But if I try to do the same with table creation, I always get warned that the table already exists, because it went ahead and tried to create my table and ignored the conditional statement. Just try running the following statement twice, you'll see what I mean:

IF NOT EXISTS (
    SELECT 1
    FROM sysobjects
    WHERE name = 'a_table'
    AND type = 'U'
)
CREATE TABLE a_table (
    col1 int not null,
    col2 int null
)
GO

Running the above produces the following error:

*SQL Server Error on (localhost) Error:2714 at Line:7 Message:There is already an object named 'a_table' in the database.*

What's the deal with that?!

A: 
IF object_id('a_table') IS NULL
BEGIN
 CREATE TABLE a_table (
  col1 int not null,
  col2 int null
 ) 
END
eed3si9n
No, this fails too. Same error.
ninesided
+2  A: 

The only workaround I've come up with so far is to use execute immediate:

IF NOT EXISTS (
    SELECT 1
    FROM sysobjects
    WHERE name = 'a_table'
    AND type = 'U'
)
EXECUTE("CREATE TABLE a_table (
    col1 int not null,
    col2 int null
)")
GO

works like a charm, feels like a dirty hack.

ninesided
A: 

It's not a function of being logged in as sa or such, is it? Can you check to see if you are creating a type "U" table in the SP (as compared to immediate mode)?

Or try it without the "U" test.

le dorfier
No, I wondered that, it doesn't seem to matter whether I'm logged in as sa, dbo or a regular user. Tables are definitely 'U' type.
ninesided
Two more longer shots come to mind. Are you double checking to make sure you are executing the "GO" command after each segment (it's easy for me to miss it if I'm using the old sybase-style command editor with select-and-ctrl-E).Have you tried the long user-qualified table names?
le dorfier
definitely executing the go after each segment, tried a number of times and qualifying user (dbo) doesn't seem to help either :(
ninesided
Maybe try qualifying with database name, too. Do you have a USE statement in there somewhere? Maybe put a statement in the SP to indicate what your current database context is. You don't have a duplicate table in master or tempdb?
le dorfier
+2  A: 

I haven't tested this, but you could try moving the create table statement into a sproc. You could then conditionally call that sproc based on your existing if statement.

AdamH
A: 

Try using Begin and End.

IF NOT EXISTS ( SELECT Count(1) FROM sysobjects WHERE name = 'a_table' AND type = 'U' ) BEGIN CREATE TABLE a_table ( col1 int not null, col2 int null ) END GO

SquidScareMe
sorry, no dice. "There is already an object named 'a_table' in the database".
ninesided
A: 

Assign the "CREATE TABLE" statement in a char @variable and then do an EXEC(@variable).

B0rG
+2  A: 

There is no other way than calling create table in execute("create table ...")

SYBASE Manual says:

When a create table command occurs within an if...else block or a while loop, Adaptive Server creates the schema for the table before determining whether the condition is true. This may lead to errors if the table already exists. To avoid this situation, either make sure a view with the same name does not already exist in the database or use an execute statement, as follows:

if not exists (select * from sysobjects where name="my table") begin execute "create table mytable(x int)" end

Vinay