我的SQL服务器查询无法识别表是否存在

时间:2017-08-11 11:24:04

标签: sql-server

this question有关:我试图使用以下查询

IF NOT EXISTS(
    SELECT T.name FROM SYS.TABLES T JOIN SYS.SCHEMAS S ON (T.SCHEMA_ID = S.SCHEMA_ID) 
    WHERE S.NAME = 'DBO' AND T.NAME = 'sample2Prot'
    ) 
BEGIN CREATE TABLE[TCPDUMP].[dbo].[sample2Prot] 
    (
    [IdTransmission] INT IDENTITY(1, 1) NOT NULL,
    [timestp]  NVARCHAR(32) NULL,
    [idq]  NVARCHAR(32) NULL,
    [idz]  NVARCHAR(32) NULL,
    [prot]  NVARCHAR(32) NULL,
    [Lhowmany]  NVARCHAR(32) NULL,
    [Rhowmany]  NVARCHAR(32) NULL,
    CONSTRAINT[PK_TCPDump] PRIMARY KEY CLUSTERED([IdTransmission] ASC)
    ) 
END;

CREATE my_table.."部分有效,但如果表已经存在,程序会在执行期间引发错误:似乎"如果不存在"声明不起作用。有人有解释吗?

随时询问更多详情

Teh error <3

2 个答案:

答案 0 :(得分:1)

您提供的示例脚本是无效的语法,因此我们只能猜测实际脚本无法按预期工作的原因,假设实际语法有效。我希望该方法可以工作,但可以重构如下:

IF OBJECT_ID(N'dbo.my_table', 'U') IS NULL
BEGIN
    CREATE TABLE dbo,my_table(col1 int);
END;

修改 修订后的问题中的实际脚本显示表名是使用数据库名称限定的,但系统目录视图不是。因此,检查当前数据库是否存在对象,如果脚本从不同的数据库上下文运行并且该表已存在,则会出现错误。修改后的脚本将是:

IF NOT EXISTS(
    SELECT T.name FROM TCPDUMP.sys.tables T JOIN TCPDUMP.sys.schemas S ON (T.SCHEMA_ID = S.SCHEMA_ID) 
    WHERE S.NAME = 'dbo' AND T.NAME = 'sample2Prot'
    ) 
BEGIN CREATE TABLE[TCPDUMP].[dbo].[sample2Prot] 
    (
    [IdTransmission] INT IDENTITY(1, 1) NOT NULL,
    [timestp]  NVARCHAR(32) NULL,
    [idq]  NVARCHAR(32) NULL,
    [idz]  NVARCHAR(32) NULL,
    [prot]  NVARCHAR(32) NULL,
    [Lhowmany]  NVARCHAR(32) NULL,
    [Rhowmany]  NVARCHAR(32) NULL,
    CONSTRAINT[PK_TCPDump] PRIMARY KEY CLUSTERED([IdTransmission] ASC)
    ) 
END;

另外,请注意系统目录视图的小写字母和此示例中的模式名称。这将确保脚本在具有区分大小写的排序规则的数据库上成功。

您还可以使用包含3个部分名称的OBJECT_ID函数:

IF OBJECT_ID(N'TCPDUMP.dbo.my_table', 'U') IS NULL

答案 1 :(得分:0)

无法使用此代码进行复制:

IF NOT EXISTS(SELECT T.name FROM SYS.TABLES T JOIN SYS.SCHEMAS S ON (T.SCHEMA_ID = S.SCHEMA_ID) WHERE S.NAME = 'DBO' AND T.NAME = 'MY_TABLE') 

BEGIN
    PRINT 'Creating table'
    CREATE TABLE MY_TABLE
    (
        ID INT 
    )
END

如果这不起作用,您能告诉您正在运行的版本以及提供的确切消息吗?