trigger 問題,寫一個Table update 另一個Table |
答題得分者是:herbert2
|
weiliching
初階會員 發表:53 回覆:78 積分:31 註冊:2003-12-27 發送簡訊給我 |
|
herbert2
尊榮會員 發表:58 回覆:640 積分:894 註冊:2004-04-16 發送簡訊給我 |
|
weiliching
初階會員 發表:53 回覆:78 積分:31 註冊:2003-12-27 發送簡訊給我 |
|
herbert2
尊榮會員 發表:58 回覆:640 積分:894 註冊:2004-04-16 發送簡訊給我 |
Sorry! 只看到您 WHERE 寫錯位置, 沒多想故漏注意您的 Set = 的寫法也錯了.
因不熟悉 MS-SQL 語法細節, 僅以 SQL-92 標準寫法試改如下: UPDate M_ReceiptD Set M_ReceiptD.M_DeclareDate = (SELECT M_ARM.M_DeclareDate FROM M_ARM Where M_ReceiptD.M_ARNo = M_ARM.M_ARNo); UPDate M_ReceiptD A
Set A.M_DeclareDate = (SELECT B.M_DeclareDate FROM M_ARM B Where A..M_ARNo = B.M_ARNo); 延伸, UPDATE 多個 Column: UPDATE Table1 A SET (A.Column1,A.Column2,A.Column3,......) = (SELECT B.Col1,B.Col2,B.Col3,...... FROM Tabel2 B WHERE A.Key1 = B.Key1 AND A.key2 = B.Key2 ......); |
weiliching
初階會員 發表:53 回覆:78 積分:31 註冊:2003-12-27 發送簡訊給我 |
|
herbert2
尊榮會員 發表:58 回覆:640 積分:894 註冊:2004-04-16 發送簡訊給我 |
因您未言明目的, 故依您語法猜測而答.
上回所寫的 SQL 確實是更新整個 M_ReceiptD 檔. 若您只是要更新一筆, 則絕對不可用 DOS DBase III 的想法去寫, 因在 Data Base 中, 並不像 DBase III 那樣, M_ReceiptD.M_ARNo 是目前 M_ReceiptD 檔所在那筆的 M_ARNo (根本沒有目前所在那筆), 而是整個 M_ReceiptD 檔全部 Rows 的 M_ARNo. 在 M_ARM 檔的 Trigger 要更新 M_ReceiptD 檔中的一筆的寫法為: UPDate M_ReceiptD Set M_DeclareDate = :New.M_DeclareDate Where M_ARNo = :New.M_ARNo; (:New.M_DeclareDate 與 :New. M_ARNo 為 M_ARM 檔剛 Update 那 Row 的新欄值, 若 M_ReceiptD.M_ARNo 非 Unique, 則可能會更新 M_ReceiptD 檔中的多筆) |
weiliching
初階會員 發表:53 回覆:78 積分:31 註冊:2003-12-27 發送簡訊給我 |
|
herbert2
尊榮會員 發表:58 回覆:640 積分:894 註冊:2004-04-16 發送簡訊給我 |
今初閱 MS-SQL 有關 Trigger 的簡介, 發現它與 Oracle 很不同.
Oracle Update 時, 產生 :Old 與 :New 兩個與 Table 同結構的 Cursor, Trigger 有 FOR EACH ROW 的語法使 Trigger 針對每一筆資料做反應. MS-SQL 則產生 DELETED 與 INSERED 兩個與 Table 同結構的系統臨時 Table. Trigger 無 FOR EACH ROW 的語法限制 Trigger 針對每一筆資料做反應, 是自動針對每一筆資料做反應嗎? 我尚不確定. Oracle 有 SELECT ColName INTO Variable FROM Table WHERE .... 語法, MS-SQL 則為 SELECT ColName INTO Table2 FROM Table1 WHERE .... (或許我沒看到較完整的資訊?) 或 SELECT @Variable = ColName FROM Table WHERE .... Oracle 以『;』做為一個 Statement 的結束, MS-SQL 則由 Compiler 自動判定, 一句 Statement 可有多 Rows, 與另一句 Statement 只須換 Row 即可. 故, 這個 Trigger 似乎該寫成: UPDATE M_ReceiptD SET M_DeclareDate = (SELECT M_DeclareDate FROM INSERTED) WHERE M_ARNo = (SELECT M_ARNo FROM INSERTED) GO 或使用變數: DECLARE @NewDate CHAR(20), @NewNo CHAR(20) SELECT @NewDate = M_DeclareDate FROM INSERTED SELECT @NewNo = M_ARNo FROM INSERTED UPDate M_ReceiptD Set M_DeclareDate = @NewDate WHERE M_ARNo = @NewNo GO 但您這 Trigger 有個問題, 若一次 UPDATE 多筆 M_ARM, 且 MS-SQL 之該 Trigger 並非針對每一筆資料做反應, 那就不能寫得這麼陽春了. 因 Trigger 不是只針對您前端的 AP 做反應, 直接從資料庫下 UPDATE 指令它也一樣被觸發, 故或許改使用 Stored Procedure 處理會比用 Trigger 處理較安全、方便. 還有, M_ARM.M_ARNo 不會被修改嗎? 否則應該也要考慮吧?!
編輯記錄
herbert2 重新編輯於 2011-10-12 02:24:47, 註解 無‧
|
weiliching
初階會員 發表:53 回覆:78 積分:31 註冊:2003-12-27 發送簡訊給我 |
已解決~程式我已改寫成, 謝謝指導~
declare @new_M_DeclareDate datetime, @old_M_ARNo varchar(20) set @new_M_DeclareDate=(select M_DeclareDate from inserted) set @old_M_ARNo=(select M_ARNo from deleted) IF UPDATE(M_DeclareDate) begin UPDate M_ReceiptD Set M_ReceiptD.M_DeclareDate = @new_M_DeclareDate Where M_ReceiptD.M_ARNo=@old_M_ARNo end Go |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |