我的表结构如下:
GLPERIOD :
periodid char
strtdate datetime
closdate datetime
fiscalyr char
GLPOST :
postdate datetime
account char
amount money
请记住,以下存储过程的参数定义为与表列所需类型相同的类型,因此在调用时不会返回任何内容。
PROCEDURE MonthlyActual
@P2 CHAR, @P3 CHAR, @P4 CHAR
SELECT SUM(amount)
FROM GLPOST
WHERE account = @P2
AND postdate BETWEEN (SELECT strtdate
FROM GLPERIOD
WHERE periodid = @P3 AND fiscalyr = @P4) AND
(SELECT closedate
FROM GLPERIOD
WHERE periodid = @P3 AND fiscalyr = @P4)
GROUP BY
account
我尝试这样称呼它:
MonthlyActual @P2 = '51080-000', @P3 = 1, @P4 = 2018
MonthlyActual @P2 = '51080-000', @P3 = '1', @P4 = '2018'
...什么也没得到。但是,如果我对这些值进行硬编码,则代码可以完美运行。 我在做什么错了?
我正在Windows Server上使用SQL Server Management Studio。
答案 0 :(得分:4)
我猜您的存储过程如下:
create stored procedure MonthlyActual (
@p2 char,
@p3 char,
@p4 char
)
如果是这样,问题很简单。声明是针对单个字符的。将它们更改为更合理的类型:
create stored procedure MonthlyActual (
@account varchar(255),
@periodid varchar(255),
@year varchar(255)
)
我还建议重命名参数,以使代码更有意义。
道德?在SQL Server中,总是始终将长度与char()
和相关类型一起使用。默认长度因上下文而异,并且经常会引入难以调试的错误。
答案 1 :(得分:3)
首先将between
的两个日期移到单独的语句中:
Declare @StartDate as datetime
Declare @EndDate as datetime
Set @StartDate = SELECT strtdate FROM GLPERIOD WHERE periodid = @P3 AND fiscalyr = @P4
Set @EndDate = SELECT closdate FROM GLPERIOD WHERE periodid = @P3 AND fiscalyr = @P4
SELECT
SUM(amount)
FROM
GLPOST
WHERE
account = @P2
AND postdate BETWEEN @StartDate AND @EndDate
GROUP BY
account
接下来,注释掉ween语句,看看它是否返回数据。如果是这样,那么您就知道问题出在日期数据
答案 2 :(得分:1)
问题在于,尽管periodid
和fiscalyr
属于char
数据类型,但将char
值传递给它们却没有结果-因为它们没有被修剪。尽管periodid
和fiscalyr
只能容纳整数,但是大约20年前设计的数据库这一事实也意味着中等习惯在起作用。具体来说,periodid = '1'
的相等性从未经历过,因为它被存储为'1'。
将检查设置为WHERE LTRIM( RTRIM( periodid ) ) = LTRIM( RTRIM( @P3 ) )
解决了该问题。