iT邦幫忙

1

SQL Tigger 造成的 [Err] 21000

請教SQL高手

假若我有一個 SQL Table
https://ithelp.ithome.com.tw/upload/images/20190821/20020633ScD5LLWQ9p.jpg

我想對其中的這二筆做修改資料
就會出現如下的錯誤訊息
https://ithelp.ithome.com.tw/upload/images/20190821/20020633ZsnwAABfsq.jpg

經判定,是我寫的SQL-Tigger造成的
https://ithelp.ithome.com.tw/upload/images/20190821/20020633LKfdBPbtFM.jpg
如果我把這 Tigger 停掉不用
上面的 SQL-Update 就可以成功

但我不懂的是
為什麼 Tigger 寫的程式、欄位,都與本次update的欄位都無關
為何會有 [Err] 21000 的錯誤??

接下來我又測試
若我把那二筆,用一筆、一筆的修改卻又可以成功?
https://ithelp.ithome.com.tw/upload/images/20190821/20020633rt99JwScIw.jpg

我的 SQL-Tigger是有什麼樣的問題
我該如何修改成不會有這樣的錯誤?

請大家幫忙,謝謝

Homura iT邦高手 1 級 ‧ 2019-08-21 16:52:13 檢舉
Trigger?....
https://stackoverflow.com/questions/42503468/update-trigger-for-multiple-rows

因為你的update 指令影響的不只一筆 record, 所以那裡的 inserted 無法直接使用 = 之類的運算子.
可以參考那個 stackoverflow 的回答,也有相關key word了.這是蠻有意思的問題.希望你能研究出來,再跟大家分享.
我沒安裝SQL Server. 看後續有沒有其他人用SQL Sever試看看.
hisniper iT邦新手 2 級 ‧ 2019-09-18 13:38:08 檢舉
一級屠豬士
太感謝你了
你提供的方法解決了我的問題
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
一級屠豬士
iT邦新手 2 級 ‧ 2019-08-22 12:19:49
最佳解答
-- 使用 PostgreSQL 
-- create trigger 時有 for each row
-- 這樣就能避免上面的情況
-- 提供你參考

create table ithelp190822 (
  id int generated always as identity primary key
, mg001 text not null
, mg002 text not null
, mg201 numeric(12,6) not null
);

insert into ithelp190822 (mg002, mg001, mg201)
values
('6400VV', '2423118', 333.000000),
('6400VV', '2423927', 333.000000);

insert into ithelp190822 (mg002, mg001, mg201)
values
('#6300VV', '2423927', 333.000000);

--
create or replace function trifun_ithelp190822()
returns trigger
as
$$
begin
    if left(new.mg002, 1) = '#'
    then
        raise exception '不可修改#開頭的項目';
    end if;
    return new;
end;
$$ language plpgsql;

create trigger tri_bu_ithelp190822
before update on ithelp190822
for each row execute procedure trifun_ithelp190822();

--
[miku]# \d ithelp190822
                           Table "miku.ithelp190822"
+--------+---------------+-----------+----------+------------------------------+
| Column |     Type      | Collation | Nullable |           Default            |
+--------+---------------+-----------+----------+------------------------------+
| id     | integer       |           | not null | generated always as identity |
| mg001  | text          |           | not null |                              |
| mg002  | text          |           | not null |                              |
| mg201  | numeric(12,6) |           | not null |                              |
+--------+---------------+-----------+----------+------------------------------+
Indexes:
    "ithelp190822_pkey" PRIMARY KEY, btree (id)
Triggers:
    tri_bu_ithelp190822 BEFORE UPDATE ON ithelp190822 FOR EACH ROW EXECUTE PROCEDURE trifun_ithelp190822()
    
---
update ithelp190822
set mg201 = 555
where mg002 = '6400VV';

UPDATE 2
Time: 3.967 ms
[miku]# commit;
COMMIT
Time: 2.298 ms
[miku]# select * from ithelp190822;
+----+---------+---------+------------+
| id |  mg001  |  mg002  |   mg201    |
+----+---------+---------+------------+
|  3 | 2423927 | #6300VV | 333.000000 |
|  1 | 2423118 | 6400VV  | 555.000000 |
|  2 | 2423927 | 6400VV  | 555.000000 |
+----+---------+---------+------------+
(3 rows)

update ithelp190822
set mg201 = 666
where mg002 = '#6300VV';

ERROR:  P0001: 不可修改#開頭的項目

select * from ithelp190822;
+----+---------+---------+------------+
| id |  mg001  |  mg002  |   mg201    |
+----+---------+---------+------------+
|  3 | 2423927 | #6300VV | 333.000000 |
|  1 | 2423118 | 6400VV  | 555.000000 |
|  2 | 2423927 | 6400VV  | 555.000000 |
+----+---------+---------+------------+

0
pilipala
iT邦新手 2 級 ‧ 2020-08-27 14:01:17

MS SQL 可以這樣寫,參考看看

IF EXISTS
	(
		SELECT * 
		FROM inserted
		WHERE LEFT(MG002 , 1) = '#'
	)
	BEGIN
		RAISERROR('不可修改 # 開頭的項目' , 16 , 10)
	END

我要發表回答

立即登入回答