T-SQL和存储过程使用相同的查询给出不同的结果

时间:2018-04-06 18:20:56

标签: sql-server tsql stored-procedures between

我是小组新手。有一个奇怪的问题。我的T-SQL查询返回69行,但存储过程中的相同查询返回零结果。

在StackOverflow的一篇帖子中,有人在EXEC语句中切换了参数/变量,但这对我来说也不起作用,如下所示。

我还尝试使用BETWEEN>=而不是<=,而不是SELECT T1.CustKey FROM INVOICEROWS T0 INNER JOIN INVOICE T1 ON T1.INVKEY = T0.INVKEY INNER JOIN ITEMS T2 ON T2.PARTCODE = T0.PARTCODE INNER JOIN CUSTOMERS T5 ON T5.CustKey = T1.CustKey WHERE T1.INVDATE BETWEEN '2018-03-26' AND '2018-03-26' AND ((T1.CustKey BETWEEN 'ABC' AND 'ABC') OR (T5.CustGroupKey = '')) AND ((T0.ItemKey BETWEEN 'PQR' AND 'STU') OR (T2.ItemGroupKey = '')) ,但没有运气。

谢谢。

ALTER PROCEDURE [dbo].[PROC1]
    (@DATEFROM AS DATE,
     @DATETO AS DATE,
     @CUSTKEYFROM AS NVARCHAR,
     @CUSTKEYTO AS NVARCHAR,
     @CUSTGROUPKEY AS SMALLINT,
     @ItemKeyFrom NVARCHAR(20),
     @ItemKeyTo NVARCHAR(20),
     @ItemGroupKey NVARCHAR(11)
    )
AS
BEGIN
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    SELECT 
        T1.CustKey
    FROM 
        INVOICEROWS T0 
    INNER JOIN 
        INVOICE T1 ON T1.INVKEY = T0.INVKEY 
    INNER JOIN 
        ITEMS T2 ON T2.PARTCODE = T0.PARTCODE  
    INNER JOIN 
        CUSTOMERS T5 ON T5.CustKey = T1.CustKey
    WHERE 
        T1.INVDATE BETWEEN @DATEFROM AND @DATETO
        AND ((T1.CustKey BETWEEN @CUSTKEYFROM AND @CUSTKEYTO) OR (T5.CustGroupKey = @CUSTGROUPKEY))
        AND ((T0.ItemKey BETWEEN @ItemKeyFrom AND @ItemKeyTo) OR (T2.ItemGroupKey = @ItemGroupKey))
END

结果:69行具有相同的值'ABC'(这是正确的)

EXEC PROC1 '2018-03-26', '2018-03-26', 'ABC', 'ABC', '', 'PQR', 'STU', '' 

运行此存储过程:

EXEC PROC1 '2018-03-26', '2018-03-26', 'ABC', 'PQR', '', 'ABC', 'STU', '' 

返回零行

{{1}}

也会返回零行

2 个答案:

答案 0 :(得分:4)

我打赌你的问题是两个存储过程参数的错误声明

ALTER PROCEDURE [dbo].[PROC1]
    (@DATEFROM AS DATE,
     @DATETO AS DATE,
     @CUSTKEYFROM AS NVARCHAR,
     @CUSTKEYTO AS NVARCHAR,
     @CUSTGROUPKEY AS SMALLINT,
     @ItemKeyFrom NVARCHAR(20),
     @ItemKeyTo NVARCHAR(20),
     @ItemGroupKey NVARCHAR(11)
    )

您将@CUSTKEYFROM@CUSTKEYTO声明为NVARCHAR。这意味着:你得到一串正好一个字符长度的字符串!这很少是你期望或想要的......

尝试使用长度声明这两个参数 - 因为您应该始终这样做! - 我打赌你的存储过程将返回所需的结果!

ALTER PROCEDURE [dbo].[PROC1]
    (@DATEFROM AS DATE,
     @DATETO AS DATE,
     -- add explicit LENGTH to the NVARCHAR! However long you need it
     @CUSTKEYFROM AS NVARCHAR(25),
     @CUSTKEYTO AS NVARCHAR(25),

请参阅Bad habits to kick : declaring VARCHAR without (length),了解这个&#34;坏习惯&#34;那你应该踢 - 现在

答案 1 :(得分:2)

在存储过程中,您已将@CUSTGROUPKEY参数声明为SMALLINT,但在查询中,您将T5.CustGroupKey与''进行比较。当您将值''传递给SMALLINT参数时,它变为0,当您将其与nvarchar列进行比较时,您正在搜索'0' ,您在比较之前强制将该列中的所有值转换为smallint(由于数据类型的优先级)。虽然错误的参数类型可能会导致错误,但这并不是您没有得到任何结果的原因。请参阅marc_s的答案。