Inconsistant结果:“select * from sysobjects,其中ID = object_ID(N'TableName')和OBJECTPROPERTY(ID,N'IsUserTable')= 1”

时间:2017-03-28 23:01:11

标签: sql-server-2012

我在本地编写了我们的开发数据库。我们的应用程序中的存储过程在整个地方都有代码,用于检查表是否存在,如果存在,则删除表并重新创建表。我注意到,当我在本地数据库中运行代码时,检查表是否存在与在开发中运行时的工作方式不同。特别是,我注意到OBJECTPROPERTY(ID,N'IsUserTable')在本地运行时返回NULL但在DEV中返回1。

if exists (select * from [CLASS].DBO.sysobjects where ID = object_ID(N'[CLASS].DBO.[CDB_SCRB_CLIENT_ACCOUNT]') and OBJECTPROPERTY(ID, N'IsUserTable') = 1)
BEGIN
    PRINT 'EXISTS!'
    drop table [CLASS].DBO.[CDB_SCRB_CLIENT_ACCOUNT]
END
    ELSE PRINT 'NO!'
GO

CREATE TABLE [CLASS].DBO.[CDB_SCRB_CLIENT_ACCOUNT] (
    [CLIENT_ID] [bigint] NULL ,
    [CLIENT_Name] [char] (70) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
    [GOC] [char] (3) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
    [AC_DATE] [datetime] NULL ,
    [EFF_Date] [datetime] NULL ,
    [AC_STATUS] [char] (8) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [REPORTING_DATE] [datetime] NULL,
    [V2V_IND] [char] (1) NULL,  --2017.10
    [LAST_OPER_ID] [char] (8) NULL,
    [LAST_TIMESTAMP] [datetime] NULL
) ON [PRIMARY]
GO
NO!
Msg 2714, Level 16, State 6, Line 2
There is already an object named 'CDB_SCRB_CLIENT_ACCOUNT' in the database.
.

我知道如果我更改支票如下

if exists (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[CDB_SCRB_CLIENT_ACCOUNT]') AND type in (N'U'))
drop table [CLASS].DBO.[CDB_SCRB_CLIENT_ACCOUNT]

它会起作用,但我不想改变这些代码的许多出现只是为了在我的本地数据库上运行应用程序。

SELECT @@version --on dev server
Microsoft SQL Server 2012 (SP3-CU7) (KB3205051) - 11.0.6579.0 (X64) 
    Dec 22 2016 11:18:09 
    Copyright (c) Microsoft Corporation
    Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)

SELECT @@version --on local workstation
Microsoft SQL Server 2012 (SP1) - 11.0.3156.0 (X64) 
    May  4 2015 18:48:09 
    Copyright (c) Microsoft Corporation
    Developer Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)

当我在每个表中编写表格时,它们看起来是一样的。有什么可以解释这个区别?

1 个答案:

答案 0 :(得分:1)

您遇到的问题是OBJECTPROPERTY的范围限定为当前数据库。您可以在OBJECT_ID调用中使用object_type选项,而不是使用它(所以OBJECT_ID(N'Database.Schema.ObjectName', 'U'),其中U代表用户表(您可以在{type列中检查相关的object_type值。 3}})。

您还可以通过检查object_id的存在来简化查询,因此无需再次查询该数据库中的sys.objects。

这会使您的查询如下所示:

IF (SELECT object_ID(N'[CLASS].DBO.[CDB_SCRB_CLIENT_ACCOUNT]', 'U')) IS NOT NULL
BEGIN
    PRINT 'EXISTS!'
    drop table [CLASS].DBO.[CDB_SCRB_CLIENT_ACCOUNT]
END
    ELSE PRINT 'NO!'
GO

CREATE TABLE [CLASS].DBO.[CDB_SCRB_CLIENT_ACCOUNT] (
    [CLIENT_ID] [bigint] NULL ,
    [CLIENT_Name] [char] (70) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
    [GOC] [char] (3) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
    [AC_DATE] [datetime] NULL ,
    [EFF_Date] [datetime] NULL ,
    [AC_STATUS] [char] (8) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [REPORTING_DATE] [datetime] NULL,
    [V2V_IND] [char] (1) NULL,  --2017.10
    [LAST_OPER_ID] [char] (8) NULL,
    [LAST_TIMESTAMP] [datetime] NULL
) ON [PRIMARY]
GO