【问题标题】:T-SQL ISNULL() incorrect behaviour with reserved word 'Primary' (SQL Server 2014)T-SQL ISNULL() 使用保留字“Primary”的错误行为 (SQL Server 2014)
【发布时间】:2015-10-02 17:21:23
【问题描述】:

前几天我遇到了这个问题,它不是一个专业,因为我可以解决它,但想知道是否有人可以提供任何见解,或者我是否发现了一个不起眼的错误?

我们有一个旧的数据库表,它有一个名为 Primary 的列,这显然是一个保留字。在运行 T-SQL 查询时,我遇到了一些奇怪的结果,这似乎表明 ISNULL 函数将列名视为保留字。是因为周五晚了,我在这里遗漏了一些非常明显的东西,还是这里发生了一些奇怪的事情?

这里有一些简单的 SQL 来设置几个测试表来说明它。

CREATE TABLE [dbo].[Customer]
(
    [CustomerID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NOT NULL,

    CONSTRAINT [PK_Customer] 
        PRIMARY KEY CLUSTERED ([CustomerID] ASC)
) ON [PRIMARY]

CREATE TABLE [dbo].[OrderTaken]
(
    [OrderID] [int] IDENTITY(1,1) NOT NULL,
    [Description] [varchar](50) NOT NULL,
    [CustomerID] [int] NOT NULL,
    [Primary] [bit] NOT NULL,

    CONSTRAINT [PK_Order] 
        PRIMARY KEY CLUSTERED ([OrderID] ASC)
) ON [PRIMARY]

ALTER TABLE [dbo].[OrderTaken] WITH CHECK 
   ADD CONSTRAINT [FK_Order_Customer] 
   FOREIGN KEY([CustomerID]) REFERENCES [dbo].[Customer] ([CustomerID])
GO

ALTER TABLE [dbo].[OrderTaken] CHECK CONSTRAINT [FK_Order_Customer]
GO

INSERT INTO [dbo].[Customer](Name) VALUES('Bob')
INSERT INTO [dbo].[Customer](Name) VALUES('Dave')
INSERT INTO [dbo].[Customer](Name) VALUES('Fred')
INSERT INTO [dbo].[Customer](Name) VALUES('Paul')
GO

INSERT INTO [dbo].[OrderTaken](Description, CustomerID, [Primary]) 
VALUES ('Order1', 1, 1)
INSERT INTO [dbo].[OrderTaken](Description, CustomerID, [Primary]) 
VALUES('Order2', 2, 1)
INSERT INTO [dbo].[OrderTaken](Description, CustomerID, [Primary]) 
VALUES('Order3', 2, 1)
INSERT INTO [dbo].[OrderTaken](Description, CustomerID, [Primary]) 
VALUES('Order4', 3, 0)
INSERT INTO [dbo].[OrderTaken](Description, CustomerID, [Primary]) 
VALUES('Order5', 3, 0)
Go

这是查询

SELECT 
    C.CustomerID, C.Name,
    O.OrderID, ISNULL(O.[OrderID], -1),
    O.[Primary], ISNULL(O.[Primary], -1) as Weird
FROM 
    Customer C
LEFT JOIN 
    OrderTaken O ON C.CustomerID  = O.CustomerID

请注意,对于没有订单的客户行,O.Primary 为 NULL ,但 ISNULL(O.[Primary],-1) 返回 1 而不是 -1

【问题讨论】:

    标签: sql-server sql-server-2014 isnull


    【解决方案1】:

    问题不在于字段名称,而在于字段类型 - bit。 它不能保存-1 值,只有01。当 SQL Server 尝试将值更改为 -1 时,它会检查 -1 <> 0 并设置 1 (true)。见documentation

    所以在检查之前转换字段:

    SELECT 
        C.CustomerID,
        C.Name,
        O.OrderID,
        ISNULL(O.[OrderID],-1),
        O.[Primary],
        ISNULL(CONVERT(int,O.[Primary]),-1) as Weird
    FROM Customer C
    LEFT JOIN OrderTaken O
    ON C.CustomerID  = O.CustomerID
    

    或将列类型更改为inttinyint

    【讨论】:

    • 哇!所以是周五晚了,我应该在周一看看。为我直言欢呼{:O)
    猜你喜欢
    • 1970-01-01
    • 2018-05-14
    • 2010-11-29
    • 1970-01-01
    • 2018-11-22
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 2017-05-13
    相关资源
    最近更新 更多