重复SQL Server错误“在期望条件的上下文中指定的非布尔类型的表达式”。

时间:2017-09-16 22:49:05

标签: sql-server tsql

阅读关于非常相似的错误的其他帖子,我相信我的情况有点不同。这是代码:

DELETE FROM comp_system_location
WHERE (system_id, location_id) IN
    (
    SELECT 
        csl.system_id,
        csl.location_id
    FROM comp_system_location AS csl
        INNER JOIN orgn_location AS ol ON csl.location_id = ol.location_id
    WHERE 
        ol.building_id IN (1, 3, 4)
        AND 
            (
            csl.system_id IN (29, 35)
            AND csl.location_id NOT IN (40, 41, 43, 44, 46, 47)
            )
        OR
            (
            csl.system_id NOT IN (29, 35)
            AND csl.location_id IN (40, 41, 43, 44, 46, 47)
            )
    );

我觉得这有点不同的原因是我对WHERE子句的比较是IN。 system_id

WHERE (system_id,location_is) IN引发了错误

根据有关基于多列删除行的其他建议,这应该有效。但我以前错了......非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

SQL Server不支持IN中的元组。您需要重写为EXISTSJOINEXISTS最接近,因为它们都代表半连接,因此如下所示。

WITH ToDelete
     AS (SELECT csl.system_id,
                csl.location_id
         FROM   comp_system_location AS csl
                INNER JOIN orgn_location AS ol
                  ON csl.location_id = ol.location_id
         WHERE  ol.building_id IN ( 1, 3, 4 )
                AND ( csl.system_id IN ( 29, 35 )
                      AND csl.location_id NOT IN ( 40, 41, 43, 44,
                                                   46, 47 ) )
                 OR ( csl.system_id NOT IN ( 29, 35 )
                      AND csl.location_id IN ( 40, 41, 43, 44,
                                               46, 47 ) ))
DELETE csl
FROM comp_system_location csl
WHERE EXISTS 
(
SELECT * 
FROM ToDelete td
WHERE td.system_id = csl.system_id AND  td.location_id = csl.location_id 
);

可能没有必要在CTE中引用comp_system_location,但我不知道您的数据模型或所需的语义。

可能你只需要

DELETE csl
FROM   comp_system_location AS csl
       INNER JOIN orgn_location AS ol
         ON csl.location_id = ol.location_id
WHERE  ol.building_id IN ( 1, 3, 4 )
       AND ( csl.system_id IN ( 29, 35 )
             AND csl.location_id NOT IN ( 40, 41, 43, 44,
                                          46, 47 ) )
        OR ( csl.system_id NOT IN ( 29, 35 )
             AND csl.location_id IN ( 40, 41, 43, 44,
                                      46, 47 ) ); 

这与您的IN版本的语义不完全相同,但可能与您尝试的内容完全相同?