tags:

views:

270

answers:

3

I have a lot of code I am trying to run where I'm querying the sysobjects table to check if an object exists before I drop it and create it again.

Issue being, sometimes if I go:

if not exists (select name from sysobjects o where o.name = 'my_table' and o.type =  'U') 
CREATE TABLE my_table (..)
go

it works, no worries. However, when I came back to run it again, I get this lovely error:

SQL Server Error on (myserver) Error:2714 at Line:10 Message:There is already an object named 'my_table' in the database.

Thanks for that, SQL Programmer. I actually asked for you not to create this table if it already exists. -_-

Any ideas?

A: 

The sybase parsers object validation pass is global and not based on conditional evaluation. Even though your code can not execute CREATE TABLE the statement is still checked for syntax and applicability which fails when the system sees that the table already exists.

The only way around this that I know of is to put your create statements inside of an EXEC() which would be evaluated only if the section was executed.

Einstein
this sounds right.. but i dont have a copy of sybase to test this on
Sam Saffron
That is a little bit on the gay side, and why I still prefer oracle, even though sybase has implicit date conversion ability.
glasnt
+1  A: 

the logic to what you are doing doesn't seem quite right. based on your statement:

"I am trying to run where I'm querying the sysobjects table to check if an object exists before I drop it and create it again"

you should simply do a delete followed by a create. This way is usually better because it ensures that the table will be updated. if the table existed and you had changes, you are probably not getting what you want.

The immediate issue you are running into is an assumed db ownership that was not consistent between runs.

based on your clarification below - here is what you can do:

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[XXXX]') AND type in (N'U')) DROP TABLE [dbo].[XXXX] GO

CREATE TABLE [dbo].[XXXX(... GO

you can run this over and over again...

mson
I've tried both the "Please remove your previous version if you have one, then install this version" and "Please only install this version if you haven't a previous one". I just want a script that I can run again and again (for testing) without breaking anything along the way (multiple system codes, system errors trying to duplicate constraints, etc)
glasnt
your logic was wrong.the if exists should be used to drop not create.
mson
The 'If Exists' is used to drop, then create. Otherwise, it just creates it. My logic is not wrong.
glasnt
For reference, the same question was asked here, with my logic. I'm going with this answer provided: http://stackoverflow.com/questions/307942/how-do-i-conditionally-create-a-table-in-sybase-tsql/307991#307991
glasnt
the code snippet you had up at the top did not do the delete. it looked like it did a create only if the table did not exist.the logic in your head was probably right... the logic you documented was slightly off.
mson
Originally I was wanting to only create tables if they didn't exist yet, or completely remove procedures and views and recreate them. This was so I wasn't accidently removing massive amounts of already created data. However, I found all the tables I was required to add didn't reflect this. I apologise for my misunderstanding. It's ok now, the code compiles and is now called in a nice little shell script on a linux box somewhere in the ether.. living the happy life.
glasnt
A: 

yes, the entire batch of SQL is normalized and compiled so as to create an "execution plan" for the entire batch. During normalization, the "possible" "create table" statement is a problem if it already exists at compile time.

My solution: rename -

if exists (select 1 from ....) begin drop table xyz create table xyz_zzzz ( ... ) exec sp_rename 'xyz_zzzz','xyz' end