【问题标题】:Stored procedure returning result even thought it's not supposed to存储过程返回结果甚至认为它不应该
【发布时间】:2019-04-12 21:17:25
【问题描述】:

我有一个如下所示的存储过程:

ALTER PROCDURE [dbo].[zsp_selectallupceans_listProduction]
    (@UPCList NVARCHAR(4000),
     @EANList NVARCHAR(4000),
     @Type TINYINT)
AS
    SELECT  
        dd.UPC, dd.EAN, dd.EBAYID AS ItemID
    FROM
        ThirdPartyData AS dd 
    WHERE 
        EXISTS (SELECT 1 FROM dbo.SplitStringProduction(@UPCList,',') S1 
                WHERE dd.UPC = S1.val) 
        OR EXISTS (SELECT 1 FROM dbo.SplitStringProduction(@EANList,',') S2 
                   WHERE dd.EAN = S2.val) 
        AND dd.Type = @Type

参数传递如下:

@UPCList='709127309019',
@EanList='0709127309019',
@Type=4

“SplitStringProduction”函数如下所示:

ALTER FUNCTION [dbo].[SplitStringProduction]
    (@string NVARCHAR(MAX),
     @delimiter NVARCHAR(5)) 
RETURNS @t TABLE
           (
                val NVARCHAR(500)
           )
AS
BEGIN
    DECLARE @xml XML
    SET @xml = N'<root><r>' + replace(@string,@delimiter,'</r><r>') + '</r></root>'

    INSERT INTO @t(val)
       SELECT
           r.value('.','varchar(500)') AS item
       FROM
           @xml.nodes('//root/r') as records(r)

    RETURN
END

现在,当我从表中进行简单选择时,如下所示:

select * 
from thirdpartydata dd
where dd.UPC = '709127309019' -- note this is one of the parameters passed to the stored procedure...

我将只得到 1 个结果,其中 Type 列设置为“1”....

现在当我尝试我的存储过程时:

exec  zsp_selectallupceans_listProduction '709127309019','0709127309019',4

我仍然得到 1 个结果,即使我不应该得到任何结果,因为如果您可以看到“类型”参数设置为 4,那么应该找不到匹配的记录....

我在这里做错了什么,我似乎无法弄清楚??

【问题讨论】:

  • 当您使用 OR 时,您缺少一些括号,并且它没有按照您的预期进行评估。它找到了 UPC 所以返回一行,我想你想把两个 EXISTS 都放在 () 中
  • where 子句中使用ANDOR 时,应始终添加括号:WHERE (1=1 OR 2=2) AND x=y
  • X OR Y AND ZX OR (Y AND Z) 相同,就像X + Y * ZX + (Y * Z) 相同。始终添加大括号,使优先顺序明确,而不是隐含。

标签: sql sql-server sql-server-2008 stored-procedures logical-operators


【解决方案1】:

您需要将OR 条件括在括号内:

WHERE (
      EXISTS (SELECT 1 FROM dbo.SplitStringProduction(@UPCList,',') S1 WHERE dd.UPC=S1.val) 
   OR EXISTS (SELECT 1 FROM dbo.SplitStringProduction(@EANList,',') S2 WHERE dd.EAN=S2.val) 
) AND dd.Type = @Type

没有他们你的查询是这样的:

WHERE EXISTS (...) 
   OR (EXISTS (...) AND dd.Type = @Type)

你得到的结果是因为第一个 OR 条件匹配。

【讨论】:

    猜你喜欢
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-03
    • 2013-06-21
    • 1970-01-01
    相关资源
    最近更新 更多