Sql溢出错误,日期必须介于1/1/1753和12/12/9999之间

时间:2013-09-04 09:45:49

标签: sql sql-server sql-server-2008

从我的日期后面的Aspx代码默认为1/1/0001 00:00:00。问题是代码在我们的网络上运行良好,但是当以补丁的形式部署到客户端时,我得到了例外。 In cs code, i had a check for the same, but I dont know why its not working on client.

所以我想从SP本身来限制它。参数在Codebehind中接受值DateTime,在SP中,参数太Datetime。当我尝试将其更改为Varchar()时,无论在何处使用它都会给我带来异常。

请注意,我不能再更改CS中的代码了。我需要SP本身的SQl终端解决方案。

以下是我的SP。我尝试了什么。

CREATE PROC UP_REM_CRUD_SALESPERSON_TARGET   
(  
 @P_OPMODE INT =NULL,  
 @P_PERSONCD INT,  
 @P_TARGETRATE INT = NULL,  
 @P_FROMDATE VARCHAR(20)=NULL,  // problem here with this param, &
 @P_TODATE VARCHAR(20)=NULL,    // with this, originally both are datetime
 @P_BROKER_BOOKING_PERCENTAGE DECIMAL(18,0) = 0,  
 @P_LMBY VARCHAR(50)=NULL,  
 @P_EXECSTATUS INT OUTPUT  
)  
 AS  
 BEGIN  

  DECLARE @V_SALARY AS DECIMAL(18,0)  
  DECLARE @V_TARGET AS DECIMAL(18,0)  
  DECLARE @V_ENDDATE AS DATE =( GETDATE()+ 36500) ;  
  //Tried with this check also but its not working too
  IF @P_FROMDATE='1/1/0001 00:00:00' 
        BEGIN
            SET @P_FROMDATE = '1/1/1753 00:00:00'
        END

    IF @P_FROMDATE ='1/1/0001 00:00:00' 
        BEGIN
            SET @P_FROMDATE = '12/12/9999 23:59:59'
        END

  -- STEP 1: FETCH GROSS SALARY OF THE SALES PERSON*/  

  SET @V_SALARY  = ( SELECT TOP(1)  BD.GROSSSALARY   
       FROM REM_M_SALEPERSON SP   
        INNER JOIN  HR_EMPPAYSLIPMAS BD    
         ON SP.PERSONCD = BD.EMPCODE   INNER JOIN HR_EMPMAS EM   
         ON SP.PERSONCD = EM.EMPCODE  
       WHERE EM.EMPCODE=@P_PERSONCD  
       ORDER BY BD.MONTHPERIODCODE  DESC  )  

  -- STEP 2: CALCULATE THE TARGET OF THAT SALES PERSON USING  
  -- TARGET = RATE* SALARY   

  SET @V_TARGET = (@P_TARGETRATE * @V_SALARY);  

  -- STEP 3: CREATE A TARGET RECORD FOR THAT SALES PERSON IN TABLE REM_T_SALESPERSON_TARGET   

  IF @P_OPMODE =1  
   BEGIN  
    INSERT INTO REM_T_SALESPERSON_TARGET(SALESPERSONID,TARGETINFIGURES,TARGETACHIEVEDINFIGURES,TARGETSTARTDATE,TARGETENDDATE,LMBY,SALESTARGETRATE, BROKER_BOOKING_PERCENTAGE )  
    VALUES (@P_PERSONCD,@V_TARGET,0,GETDATE(),@V_ENDDATE,@P_LMBY,@P_TARGETRATE, @P_BROKER_BOOKING_PERCENTAGE)  
   END  

  -- STEP 4: FETCH THE RECORDS BASED ON BOOKING     
  IF @P_OPMODE = 4  
   BEGIN  
     DECLARE @TARGET_ACHIEVED AS DECIMAL(18,2)  
     DECLARE  @DIRECT_SALES AS DECIMAL(18,0)   
     DECLARE @V_SALE_TYPE AS VARCHAR(1)   
     DECLARE @MIXED_SALES AS DECIMAL(18,0)  
     DECLARE @TOTAL_DIRECT AS DECIMAL(18,0)  
     DECLARE @TOTAL_MIXED AS DECIMAL(18,0)  

     SET @TARGET_ACHIEVED =0         
     SET @DIRECT_SALES =0         
     SET @MIXED_SALES =0   
     SET @TOTAL_DIRECT =0        
     SET @TOTAL_MIXED =0        

     /*  
     IF THE FROM DATE AND TO DATES ARE PROVIDED THEN FIND THE SALES MADE INDIVIDUALLY BY THE SALES PERSON  
     AND ALSO THE SALES IN WHICH BROKERS WERE INVOLVED, IN BETWEEN THE DATE SUPPLIED.  
     */  
     IF @P_FROMDATE IS NOT NULL AND @P_TODATE  IS NOT NULL  
      BEGIN  

       -- TOTAL SALES MADE BY SALES PERSON INDIVIDUALLY  

       SET @DIRECT_SALES = (SELECT SUM(A.NETBASICPRICE)   
             FROM REM_T_APPLICANTHDR  A INNER JOIN REM_T_SALESPERSON_TARGET B   
                      ON A.SPERSONCD = B.SALESPERSONID   
             WHERE A.SPERSONCD=@P_PERSONCD AND (A.APPDT BETWEEN @P_FROMDATE  AND @P_TODATE) AND (RTRIM(LTRIM(A.AGENTCD))='' ) )  


       -- TOTAL SALES MADE BY SALES PERSON ALONGWITH AGENTS  

       SET @MIXED_SALES = (SELECT SUM(A.NETBASICPRICE)   
            FROM REM_T_APPLICANTHDR  A INNER JOIN REM_T_SALESPERSON_TARGET B   
               ON A.SPERSONCD = B.SALESPERSONID   
            WHERE A.SPERSONCD=@P_PERSONCD AND   (A.APPDT BETWEEN @P_FROMDATE  AND @P_TODATE) AND (RTRIM(LTRIM(A.AGENTCD))<>'') )  


       -- IF THE SALE TYPE IS DIRECT THEN PICK ALL AMOUNT  

       IF @DIRECT_SALES > 0  
        BEGIN  
         SET @V_SALE_TYPE = 'D'  
         SET @TOTAL_DIRECT = @DIRECT_SALES  
        END  

       -- IF SALE IS MADE WITH AGENT INVOLVED PICK 20% OF THAT SALE  

       IF @MIXED_SALES > 0  

        BEGIN  

         SET @V_SALE_TYPE ='M'  
         SET @TOTAL_MIXED = (20*@MIXED_SALES)/100;   

        END  

       /*  
       CALCULATE TOTAL TARGET ACHIEVED AS A SUM OF INDIVIDUAL SALE AND AGENT BASED SALE  
       */  
       SET @TARGET_ACHIEVED =   (ISNULL(@TOTAL_DIRECT,0)+ISNULL(@TOTAL_MIXED,0));  


       /*CREATE A TABLE OF TARGET ACHIEVEMENT REPORT WITH ALL RELEVANT DETAILS*/  

       SELECT A.EMPNAME AS SALES_PERSON_NAME,@TARGET_ACHIEVED AS TARGET_ACHIEVED,@TOTAL_DIRECT AS DIRECTSALE,@TOTAL_MIXED AS MIXEDSALE,B.TARGETINFIGURES,B.SALESTARGETRATE,  
         CASE   
          WHEN ISNULL((@TARGET_ACHIEVED - TARGETINFIGURES),0) < 0 THEN 'BELOW TARGET'  
          ELSE CONVERT(VARCHAR, ISNULL((@TARGET_ACHIEVED - TARGETINFIGURES),0))   
         END AS TARGET_DIFFERENCE  
       FROM HR_EMPMAS A   
         INNER JOIN  REM_T_SALESPERSON_TARGET B   
       ON A.EMPCODE = B.SALESPERSONID  
       WHERE A.EMPCODE = @P_PERSONCD  


           /*TARGET ACHIEVEMENT*/  
       SELECT A.APPNO,CONVERT(DATE,A.APPDT,103)AS APPDT,C.PRJNAME,A.APPLICANT,A.BROKERAGEAMT,A.BROKARAGE,A.BROKASSAMT,A.BROKON, A.NETBASICPRICE,    
        CASE WHEN A.AGENTCD <>'' THEN 'BROKER SALE' ELSE 'DIRECT SALE' END AS SALE_TYPE  
       FROM REM_T_APPLICANTHDR A INNER JOIN REM_T_SALESPERSON_TARGET B   
           ON A.SPERSONCD = B.SALESPERSONID   
           INNER JOIN REM_M_PRJHDR C ON C.PRJCD =A.PRJCD  
       WHERE A.SPERSONCD = @P_PERSONCD AND  (A.APPDT BETWEEN @P_FROMDATE AND @P_TODATE)  



       /* INCENTIVE CALCULATION  */    

       DECLARE @INCENTIVE AS DECIMAL(18,0), @COUNTER AS INT  
       --SET @COUNTER  = (SELECT COUNT(*) FROM REM_T_APPLICANTHDR  A INNER JOIN REM_T_SALESPERSON_TARGET B  
       --     ON A.SPERSONCD = B.SALESPERSONID   
       --      WHERE A.SPERSONCD = @P_PERSONCD AND  ((CONVERT(DATE,@P_FROMDATE,102) >= CONVERT(DATE,TARGETSTARTDATE,102)) AND (CONVERT(DATE,@P_TODATE,102) <= CONVERT(DATE,TARGETENDDATE,102))))  
       --IF @COUNTER > 0  
       -- BEGIN  
       --    SET @INCENTIVE = ISNULL(@COUNTER,0) * 2500;  
       -- END  

       SET @INCENTIVE = (SELECT  SUM(CASE WHEN DISCOUNT  = 0.00 THEN 0.01 * NETBASICPRICE  
                        WHEN DISCOUNT <= 0.01 THEN 0.0075 * NETBASICPRICE  
                  WHEN DISCOUNT <= 0.02 THEN 0.0050 * NETBASICPRICE  
                  ELSE 0.0025 * NETBASICPRICE   
                 END  
                +  
                CASE WHEN AGENTCD <> 0       THEN 2500.0  
                 ELSE    0.0       END)  AS INCENTIVE  
               FROM  REM_T_APPLICANTHDR  A   
                INNER JOIN REM_T_SALESPERSON_TARGET B  
                                      ON A.SPERSONCD = B.SALESPERSONID   
               WHERE A.SPERSONCD = @P_PERSONCD AND (A.APPDT BETWEEN @P_FROMDATE AND @P_TODATE)  
               GROUP BY SPERSONCD             
           )  


          SELECT ISNULL(@INCENTIVE,0) AS TOTALINCENTIVE, ISNULL(@DIRECT_SALES,0) AS TOTALDS, ISNULL(@MIXED_SALES,0) AS TOTALMS, B.TARGETINFIGURES, ISNULL(@TARGET_ACHIEVED,0) AS TOTALTA  
          FROM REM_T_APPLICANTHDR  A   
             INNER JOIN REM_T_SALESPERSON_TARGET B  
              ON A.SPERSONCD = B.SALESPERSONID    
             INNER JOIN HR_EMPMAS C   
              ON A.SPERSONCD = C.EMPCODE  
             WHERE A.SPERSONCD = @P_PERSONCD AND (A.APPDT BETWEEN @P_FROMDATE AND @P_TODATE)  


      END  
     ELSE  
      BEGIN  
       SELECT A.APPNO,A.APPDT,C.PRJNAME,A.APPLICANT,A.BROKERAGEAMT,A.BROKARAGE,A.BROKASSAMT,A.BROKON, A.NETBASICPRICE,    
        CASE WHEN A.AGENTCD <>'' THEN 'BROKER SALE' ELSE 'DIRECT SALE' END AS SALE_TYPE  
       FROM REM_T_APPLICANTHDR A   
           INNER JOIN REM_T_SALESPERSON_TARGET B   
            ON A.SPERSONCD = B.SALESPERSONID   
           INNER JOIN REM_M_PRJHDR C   
            ON C.PRJCD =A.PRJCD  
       WHERE 1=0  
      END  
   END  
 END  

1 个答案:

答案 0 :(得分:1)

您重复此块两次:

IF @P_FROMDATE ='1/1/0001 00:00:00' 
BEGIN
    SET @P_FROMDATE = '12/12/9999 23:59:59'
END

第二次应该是@P_TODATE

其次我会说使用VARCHAR表示日期很糟糕。

第三个ASP.NET端,您应该使用DateTime?而不是DateTime,因此默认值为null

另一种选择是使用datetime2作为查询的参数。它们支持全范围的.NET DateTime。但这是一个快速修复,它不能解决你不应该传递1/1/0001的真正问题!