2016-11-20 43 views
1

當我運行一個簡單的更新語句時,我不斷收到此錯誤。遊標中的轉換錯誤?

Msg 16922, Level 16, State 1, Procedure TRG_MEM_BALANCE_AWW, Line 72
Cursor Fetch: Implicit conversion from data type datetime to decimal is not allowed.

這是我的代碼,我有我的觸發器。我沒有看到什麼被錯誤地轉換了?

ALTER TRIGGER [dbo].[TRG_MEM_BALANCE_AWW] 
ON [dbo].[DETAILRENTAL] 
AFTER INSERT, DELETE, UPDATE 
AS 
BEGIN 
    IF(EXISTS(SELECT * FROM inserted) 
     AND 
     EXISTS(SELECT * FROM deleted)) 
    BEGIN 
     DECLARE CURSORFORUPDATE CURSOR FOR 
      SELECT 
       I.RENT_NUM, I.DETAIL_DUEDATE, I.DETAIL_RETURNDATE, 
       I.DETAIL_DAILYLATEFEE, D.DETAIL_DUEDATE, 
       D.DETAIL_RETURNDATE, D.DETAIL_DAILYLATEFEE 
      FROM 
       inserted I 
      INNER JOIN 
       DELETED D ON I.Rent_Num = D.Rent_Num 
          AND I.Vid_Num = D.Vid_Num 

     DECLARE @RENT_NUM INT 
     DECLARE @RETURN_DATE_NEW DATETIME 
     DECLARE @DUE_DATE_OLD DATETIME 
     DECLARE @DUE_DATE_NEW DATETIME 
     DECLARE @RETURN_DATE_OLD DATETIME 
     DECLARE @DAILY_LATE_FEE_NEW DECIMAL(5,2) 
     DECLARE @DAILY_LATE_FEE_OLD DECIMAL(5,2) 
     DECLARE @LATE_FEE_PRIOR DECIMAL(5,2) 
     DECLARE @LATE_FEE_AFTER DECIMAL(5,2) 
     DECLARE @CHANGE DECIMAL (5,2) 

     OPEN CURSORFORUPDATE 

     FETCH NEXT FROM CURSORFORUPDATE INTO @RENT_NUM, @DUE_DATE_NEW, @RETURN_DATE_NEW, @DAILY_LATE_FEE_NEW, @DUE_DATE_OLD, @RETURN_DATE_OLD, @DAILY_LATE_FEE_OLD 

     WHILE (@@FETCH_STATUS = 0) 
     BEGIN 

--A 
IF(@RETURN_DATE_OLD > @DUE_DATE_OLD) 

BEGIN 

    SELECT @LATE_FEE_PRIOR = DATEDIFF(DAY, @DUE_DATE_OLD, @RETURN_DATE_OLD) * @DAILY_LATE_FEE_OLD 

    END 
    ELSE 
     SELECT @LATE_FEE_PRIOR = 0 
--B 
    IF(@RETURN_DATE_NEW > @DUE_DATE_NEW) 
    BEGIN 
    SELECT @LATE_FEE_AFTER = DATEDIFF(DAY, @DUE_DATE_NEW, @RETURN_DATE_NEW) * @DAILY_LATE_FEE_NEW 

    END 
    ELSE 
     SELECT @LATE_FEE_AFTER = 0 

--C 
    SELECT @CHANGE = @LATE_FEE_AFTER - @LATE_FEE_PRIOR 

--D 
    IF(@CHANGE <> 0) 
    BEGIN 
    DECLARE @MEM_NUM INT 
    SELECT @MEM_NUM = M.Mem_Num 
    FROM RENTAL R INNER JOIN MEMBERSHIP M ON R.MEM_NUM = M.MEM_NUM AND R.RENT_NUM = @RENT_NUM 

    UPDATE MEMBERSHIP 
    SET Mem_Balance = MEM_BALANCE + @CHANGE 
    WHERE Mem_Num = @MEM_NUM 

    FETCH NEXT FROM CURSORFORUPDATE 
    INTO @RENT_NUM, @DUE_DATE_NEW, @DUE_DATE_OLD, @RETURN_DATE_NEW, @RETURN_DATE_OLD, @DAILY_LATE_FEE_NEW, @DAILY_LATE_FEE_OLD 

    END 
    CLOSE CURSORFORUPDATE 
    DEALLOCATE CURSORFORUPDATE 

    END 
END 
END 

更新我正在運行的是

UPDATE DETAILRENTAL 
SET DETAIL_RETURNDATE = 2013-03-10 
WHERE RENT_NUM = 1001 

這就使得在DETAILRENTAL表應更新的成員表中的成員平衡返回電影后期。任何想法如何解決這個錯誤將不勝感激。

+0

我加入了數據庫標記之前。語法顯然是SQL Server。 –

回答

0

DETAIL_RETURNDATE領域已經datetimedate類型,可能是,但你正試圖將其設置爲一個數字:2013年3月10日= 2013零下3減去10 = 2000

試試這個:

Update DETAILRENTAL 
    Set DETAIL_RETURNDATE = Convert(datetime, '2013-03-10', 23) 
    Where RENT_NUM = 1000; 

在這種情況下,Convert(datetime, , 23)可能不是絕對必要的,但如果您的輸入日期格式一致,那麼這是很好的做法。

編輯

前者可能是你的問題的根源,但我也注意到這是更可能是什麼造成的錯誤

ALTER TRIGGER [dbo].[TRG_MEM_BALANCE_AWW] 
ON [dbo].[DETAILRENTAL] 
AFTER INSERT, DELETE, UPDATE 
AS 
BEGIN 
    IF (EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)) 
    BEGIN 
     DECLARE CURSORFORUPDATE CURSOR FOR 
     SELECT I.RENT_NUM, I.DETAIL_DUEDATE, I.DETAIL_RETURNDATE,I.DETAIL_DAILYLATEFEE, 
      D.DETAIL_DUEDATE, D.DETAIL_RETURNDATE, D.DETAIL_DAILYLATEFEE 
      FROM inserted I INNER JOIN DELETED D ON I.Rent_Num = D.Rent_Num AND I.Vid_Num = D.Vid_Num 

     DECLARE @RENT_NUM INT 
     DECLARE @RETURN_DATE_NEW DATETIME 
     DECLARE @DUE_DATE_OLD DATETIME 
     DECLARE @DUE_DATE_NEW DATETIME 
     DECLARE @RETURN_DATE_OLD DATETIME 
     DECLARE @DAILY_LATE_FEE_NEW DECIMAL(5,2) 
     DECLARE @DAILY_LATE_FEE_OLD DECIMAL(5,2) 
     DECLARE @LATE_FEE_PRIOR DECIMAL(5,2) 
     DECLARE @LATE_FEE_AFTER DECIMAL(5,2) 
     DECLARE @CHANGE DECIMAL (5,2) 

     OPEN CURSORFORUPDATE 
     FETCH NEXT FROM CURSORFORUPDATE 
     INTO @RENT_NUM, @DUE_DATE_NEW, @RETURN_DATE_NEW, @DAILY_LATE_FEE_NEW, 
       @DUE_DATE_OLD, @RETURN_DATE_OLD, @DAILY_LATE_FEE_OLD 

     WHILE (@@FETCH_STATUS = 0) 
     BEGIN 
      --A 
      IF(@RETURN_DATE_OLD > @DUE_DATE_OLD) 
       SELECT @LATE_FEE_PRIOR = DATEDIFF(DAY, @DUE_DATE_OLD, @RETURN_DATE_OLD) * @DAILY_LATE_FEE_OLD; 
      ELSE 
       SELECT @LATE_FEE_PRIOR = 0; 

      --B 
      IF(@RETURN_DATE_NEW > @DUE_DATE_NEW) 
       SELECT @LATE_FEE_AFTER = DATEDIFF(DAY, @DUE_DATE_NEW, @RETURN_DATE_NEW) * @DAILY_LATE_FEE_NEW 
      ELSE 
       SELECT @LATE_FEE_AFTER = 0 

      --C 
      SELECT @CHANGE = @LATE_FEE_AFTER - @LATE_FEE_PRIOR 

      --D 
      IF(@CHANGE <> 0) 
      BEGIN 
       DECLARE @MEM_NUM INT; 
       SELECT @MEM_NUM = M.Mem_Num 
        FROM RENTAL R 
        INNER JOIN MEMBERSHIP M ON R.MEM_NUM = M.MEM_NUM AND R.RENT_NUM = @RENT_NUM 

       UPDATE MEMBERSHIP 
        SET Mem_Balance = MEM_BALANCE + @CHANGE 
        WHERE Mem_Num = @MEM_NUM 
      END -- End of IF(@CHANGE <> 0) 

      FETCH NEXT FROM CURSORFORUPDATE 
      INTO @RENT_NUM, @DUE_DATE_NEW, @RETURN_DATE_NEW, @DAILY_LATE_FEE_NEW, 
       @DUE_DATE_OLD, @RETURN_DATE_OLD, @DAILY_LATE_FEE_OLD 
     END -- End of WHILE (@@FETCH_STATUS = 0) 

     CLOSE CURSORFORUPDATE 
     DEALLOCATE CURSORFORUPDATE 
    END -- End of IF(EXISTS (Select * From Inserted) AND EXISTS (Select * From Deleted)) 
END -- end of trigger 

看來,當你第二次從光標進行讀取時,列出的變量與第一次的順序不同。所以你試圖從DETAIL_DAILYLATEFEE插入@RETURN_DATE_NEWDETAIL_RETURNDATE插入@DAILY_LATE_FEE_NEW

我認爲可能還有一些與BEGIN ... END匹配的問題。

編輯

這裏是我的測試腳本,似乎一切正常這裏。

Create Table Rental (
    Rent_Num int, 
    Mem_Num int); 
Create Table DetailRental (
    Rent_Num int, 
    Vid_Num int, 
    Detail_DueDate datetime, 
    Detail_ReturnDate datetime, 
    Detail_DailyLateFee decimal(5,2)); 
Create Table Membership (
    Mem_Num int, 
    Mem_Balance money); 

Insert Into Membership Values (1, 0); 
Insert Into Rental Values (1, 1); 
Insert Into DetailRental 
Values (1, 1, '2016-11-21', '2016-11-23', 1), 
     (1, 2, '2015-11-21', '2016-11-22', 0.5); 
Go 

然後在表上創建觸發器,按照前文的房源

Select * From DetailRental; 
Select * From Rental; 
Select * From Membership; 

Update DetailRental 
    Set Detail_ReturnDate = '2016-11-21' 
    Where Rent_Num = 1; 

Select * From Membership; 
Go 

Mem_Num Mem_Balance 
1  0.00 

Mem_Num Mem_Balance 
1  2.00 
+0

感謝您的回覆。我首先做了不同的更新語句樣式,但它不起作用。然後,我改變了獲取語句中變量的順序以便相互匹配,並再次嘗試更新語句,但仍然無法工作。我得到這個錯誤:「從字符串轉換日期和/或時間時轉換失敗」。當我嘗試使用原始方式更新語句時,出現錯誤,提示「」名稱爲「CURSORFORUPDATE」的遊標不存在。我不明白它是如何說它不存在,如果它從光標拉光標的名稱? –

+0

@AustinWeller我們可以繼續聊天嗎:http://chat.stackexchange.com/rooms/48862/chat-for-conversion-error-in-curosr – mendosi

+0

我不會反對它,但我在這個網站上的聲望是不夠高,不能很好地聊天 –