2

我有很多代码正在尝试运行,我正在查询 sysobjects 表以检查对象是否存在,然后再删除并再次创建它。

问题是,有时如果我去:

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

它有效,不用担心。然而,当我再次运行它时,我得到了这个可爱的错误:

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

谢谢你,SQL 程序员。如果它已经存在,我实际上要求你不要创建这个表。-_-

有任何想法吗?

4

3 回答 3

1

你正在做的事情的逻辑似乎不太正确。根据您的陈述:

“我正在尝试在查询 sysobjects 表的位置运行以检查对象是否存在,然后再删除并再次创建它”

您应该简单地进行删除,然后进行创建。这种方式通常更好,因为它可以确保表会被更新。如果表存在并且您进行了更改,那么您可能没有得到您想要的。

您遇到的直接问题是假定的数据库所有权在运行之间不一致。

根据您在下面的说明-您可以执行以下操作:

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

创建表 [dbo].[XXXX(... GO

你可以一遍又一遍地运行它......

于 2009-06-17T01:58:37.160 回答
0

sybase 解析器对象验证传递是全局的,不基于条件评估。即使您的代码无法执行 CREATE TABLE,仍会检查该语句的语法和适用性,当系统发现该表已存在时,该语句将失败。

我所知道的解决此问题的唯一方法是将您的 create 语句放在 EXEC() 中,只有在执行该部分时才会对其进行评估。

于 2009-06-17T01:52:34.160 回答
0

是的,整批SQL都进行了规范化和编译,从而为整批创建了一个“执行计划”。在规范化期间,如果“可能的”“create table”语句在编译时已经存在,那么它就是一个问题。

我的解决方案:重命名 -

如果存在 (select 1 from ....) begin drop table xyz create table xyz_zzzz ( ... ) exec sp_rename 'xyz_zzzz','xyz' end

于 2009-06-22T15:19:43.873 回答