2015-10-02 1 views
1

Je suis tombé sur cela l'autre jour, et ce n'était pas une majeure que je pourrais contourner, mais je me demandais si quelqu'un pouvait offrir ou avez-vous trouvé un bug obscur?T-SQL ISNULL() comportement incorrect avec le mot réservé «primaire» (SQL Server 2014)

Nous avons une ancienne table de base de données qui a une colonne appelée primaire, qui est évidemment un mot réservé. Lors de l'exécution d'une requête T-SQL, j'ai rencontré des résultats étranges qui semblent suggérer que la fonction ISNULL traite le nom de la colonne comme s'il s'agissait du mot réservé. Est-ce juste parce qu'il est tard vendredi et qu'il me manque quelque chose de vraiment évident ici, ou est-ce que quelque chose d'étrange se passe ici?

Voici quelques instructions SQL simples pour configurer quelques tables de test pour l'illustrer.

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 

et voici la requête

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 

Notez que pour la ligne de client qui ne dispose pas d'un ordre, O.Primary est NULL, mais ISNULL (O. [primaire], - 1) renvoie 1 et non -1

Répondre

3

Le problème n'est pas dans le nom du champ, mais dans le type de zone bit. Il ne peut pas contenir -1 valeur, seulement 0 et 1. Et lorsque SQL Server essaie de modifier la valeur à -1 il vérifie que -1 <> 0 et définit 1 (true). Voir documentation.

convertir donc le champ avant de vérifier:

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 

Ou changer le type de colonne à int ou tinyint.

+0

Doh! Donc, c'était qu'il était tard un vendredi et j'aurais dû regarder lundi. Salutations pour me mettre droit {: O) – PabloInNZ