-2

我写了以下stored procedure但它给出了错误,我怎样才能让它正常工作。谢谢。

/* stored procedure interestcalc writen by M */
SET ANSI_NULLS ON

SET QUOTED_IDENTIFIER ON

CREATE PROCEDURE spInterestCal
 (
    @P_NO  INT,
    @TOTAL_MONEY   INT,
    @PAYMENT_TYPE  INT,  /* if payment type is 1 then Yearly, 2 then Semi Yearly, 3 then Quaterly, 4 then Montly  */
    @INTEREST_RATE  INT,
    @START_DATE  DATE,
    @END_DATE  DATE,
  )
AS 
BEGIN

    DECLARE @INSTALLMENT_FACTOR FLOAT 
    DECLARE @INSTALLMENT_NUMBER INT
    DECLARE @INTEREST FLOAT 
    DECLARE @I INT
    DECLARE @R_INSTALLMENT_NUMBER INT
    SET @INSTALLMENT_FACTOR = 0
    SET @INSTALLMENT_NUMBER = 0
    SET @INTEREST = 0
    SET @I = 1
    SET @R_INSTALLMENT_NUMBER = 0

    /*
    DECLARE @YEARS_DIFF INT
    DECLARE @MONTHS_DIFF INT
    DECLARE @DAYS_DIFF INT
    SET @YEARS_DIFF = DATEDIFF(YYYY,@START_DATE,@END_DATE)
    SET @MONTHS_DIFF = DATEDIFF(M,@START_DATE,@END_DATE)-(datediff(YYYY,@START_DATE,@END_DATE)*12)
    SET @DAYS_DIFF = DATEPART(D,@END_DATE)-DATEPART(D,@START_DATE) 
    */

    IF (@PAYMENT_TYPE = 1)  /* if PaymentType is 1 means Yearly */
       BEGIN 
            SELECT @INSTALLMENT_FACTOR = 1;
            SELECT @INSTALLMENT_NUMBER = 1; /*Yearly So 1 INSTALLMENT */
       END

    IF (@PAYMENT_TYPE = 2)  /* if PaymentType is 2 means Semi Yearly */
       BEGIN
            SELECT @INSTALLMENT_FACTOR = 0.5;
            SELECT @INSTALLMENT_NUMBER = 2; /*Semi Yearly So 2 INSTALLMENT */
       END

    IF (@PAYMENT_TYPE = 3)  /* if PaymentType is 3 means Quaterly */
       BEGIN
            SELECT @INSTALLMENT_FACTOR = 0.25;
            SELECT @INSTALLMENT_NUMBER = 4; /*Quaterly So 4 INSTALLMENT */
       END
    IF (@PAYMENT_TYPE = 4)   /* if PaymentType is 4 means Montly  */
       BEGIN 
            SELECT @INSTALLMENT_FACTOR = 0.08;
            SELECT @INSTALLMENT_NUMBER = 12;  /*Montly So 12 INSTALLMENT */
       END 

    SELECT @R_INSTALLMENT_NUMBER = ((SELECT DATEDIFF(YEAR, @START_DATE, @END_DATE))* @INSTALLMENT_NUMBER)
    DECLARE @SMOUNT INT
    DECLARE @SYEAR INT
    SELECT @SMOUNT = (SELECT MONTH(@START_DATE))
    SELECT @SYEAR =  (SELECT YEAR(@START_DATE))

    WHILE ((SELECT @I) < = @R_INSTALLMENT_NUMBER )  /* Calculates Interest And Prints Info*/
        BEGIN
             IF (@SMOUNT > 12)
                BEGIN
                    SELECT @SYEAR +1
                END
            SELECT @R_INSTALLMENT_NUMBER = @R_INSTALLMENT_NUMBER -1
            SELECT @INTEREST = ((SELECT @TOTAL_MONEY) - (SELECT @R_INSTALLMENT_NUMBER * (SELECT @INSTALLMENT_FACTOR*(SELECT @TOTAL_MONEY)))) * ((SELECT @INTEREST_RATE)/100 ) 
            PRINT '  P_NO IS   ' + @P_NO + '  TOTAL_MONEY IS   ' + @TOTAL_MONEY + '  INSTALLMET AMOUNT IS   ' + @TOTAL_MONEY/@R_INSTALLMENT_NUMBER +  ' @INTEREST IS  '+ @INTEREST  + ' DUE DATE IS  '+ (SELECT DAY(@START_DATE))  + '/' + (@SMOUNT) + '/' +(@SYEAR) 
            SELECT @SMOUNT = @SMOUNT + @INSTALLMENT_NUMBER-1

        END    

END
GO
4

2 回答 2

1

解析查询时出现 4 个错误 - 尝试在 SQL Server Management Studio 中自行解析,您将看到:

Msg 102, Level 15, State 1, Procedure spInterestCal, Line 13
Incorrect syntax near ')'.

Msg 111, Level 15, State 1, Procedure spInterestCal, Line 18
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.

Msg 1046, Level 15, State 1, Procedure spInterestCal, Line 74
Subqueries are not allowed in this context. Only scalar expressions are allowed.

Msg 102, Level 15, State 1, Procedure spInterestCal, Line 79
Incorrect syntax near 'GO'.

如果不首先解决上述问题,您将无法检测到一些逻辑错误。

要更正第一个解析错误,只需从参数列表末尾删除虚假逗号(注意删除的逗号):

@END_DATE  DATE

第二个错误也很简单,放在GOthe 之后SET QUOTED_IDENTIFIER ON和之前CREATE PROCEDURE

SET QUOTED_IDENTIFIER ON
GO

下一个涉及您的PRINT声明,其中包含一个SELECT DAY(@START_DATE)声明 - 这是不允许的,应该删除:

DAY(@START_DATE)

最后一个正在发生,因为您END GO在程序结束时有一行。尝试:

END
GO
于 2013-03-28T09:03:31.040 回答
1

我看到两个语法错误:

1) ')' 附近的语法不正确。去掉最后一个参数后的逗号:@END_DATE

2)在这种情况下不允许子查询。只允许标量表达式

PRINT '  P_NO IS   ' + @P_NO + '  TOTAL_MONEY IS   ' + @TOTAL_MONEY + '  
   INSTALLMET AMOUNT IS   ' + @TOTAL_MONEY/@R_INSTALLMENT_NUMBER +  ' @INTEREST IS  '+ 
   @INTEREST  + ' DUE DATE IS  '+ 
   (SELECT DAY(@START_DATE))  + '/' + (@SMOUNT) + '/' +(@SYEAR)

移除且仅SELECT拥有(SELECT DAY(@START_DATE))' DUE DATE IS '+DAY(@START_DATE) + '/'

于 2013-03-28T09:04:10.617 回答