为什么我的T-SQL存储过程无法执行?

时间:2018-07-02 17:51:15

标签: sql-server tsql stored-procedures

我的表结构如下:

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。

3 个答案:

答案 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)

问题在于,尽管periodidfiscalyr属于char数据类型,但将char值传递给它们却没有结果-因为它们没有被修剪。尽管periodidfiscalyr只能容纳整数,但是大约20年前设计的数据库这一事实也意味着中等习惯在起作用。具体来说,periodid = '1'的相等性从未经历过,因为它被存储为'1'。

将检查设置为WHERE LTRIM( RTRIM( periodid ) ) = LTRIM( RTRIM( @P3 ) )解决了该问题。