• 週六. 5 月 30th, 2026

天南訊息

IT 工作者的工作紀錄

B74B 新增 Trigger 的相關 異動

個人頭像照片

By伍芳左

4 月 21, 2026

✅ 修正版 Trigger(乾淨版)

ALTER TRIGGER [dbo].[TRI_T_B74B_M]
ON [dbo].[T_B74B_M]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;— ⚠️ 假設仍為單筆(你原本就是這樣設計)
DECLARE
@單號 varchar(12), @項次 varchar(5), @品牌 varchar(20),
@工作表多頁 nvarchar(300), @AI char(1), @cRow smallint,
@工程項次 nvarchar(50), @項目說明 nvarchar(400), @單位 nvarchar(50),
@數量 varchar(20), @單價 varchar(20), @複價 varchar(20),
@備註 nvarchar(100), @牌價 varchar(20), @折數 varchar(20),
@類型 varchar(4), @項目說明_2 nvarchar(400),
@代號 varchar(20), @異動 nvarchar(10)

SELECT
@單號=單號, @項次=項次, @異動=異動,
@工程項次=工程項次,
@項目說明=TRIM(項目說明),
@單位=單位, @代號=代號, @cRow=cRow,
@項目說明_2=dbo.空白轉連接(dbo.全形轉半形(項目說明_2)),
@品牌=品牌,
@工作表多頁=工作表多頁,
@AI=AI,
@數量=數量, @單價=單價, @複價=複價,
@備註=備註, @牌價=牌價, @折數=折數, @類型=類型
FROM INSERTED;

— 數值安全轉換
IF TRY_CONVERT(decimal(18,4), @數量) IS NULL SET @數量 = ‘0’;
IF TRY_CONVERT(decimal(18,4), @單價) IS NULL SET @單價 = ‘0’;
IF TRY_CONVERT(decimal(18,4), @複價) IS NULL SET @複價 = ‘0’;
IF TRY_CONVERT(decimal(18,4), @牌價) IS NULL SET @牌價 = ‘0’;
IF TRY_CONVERT(decimal(18,4), @折數) IS NULL SET @折數 = ‘0’;

— 工程項次處理
SET @工程項次 = REPLACE(REPLACE(@工程項次, ‘.000’, ), ‘.00’, );

— 品牌處理
IF @品牌 IN (‘kurrent’,‘KURRENT’) SET @品牌=‘Kurrent’;

IF (@品牌 IS NULL) OR (@品牌 NOT IN (SELECT 品牌 FROM dbo.vi_B765))
SET @品牌=‘*’;

——————————————————
— 刪除
IF @異動=‘刪除’
BEGIN
DELETE FROM dbo.T_B74B
WHERE 單號=@單號 AND 項次=@項次;
RETURN;
END

——————————————————
— 新增
IF @異動=‘新增’
BEGIN
SELECT @項次 = MAX(項次)
FROM dbo.vi_B74B
WHERE 單號=@單號;

IF @項次 IS NULL
SET @項次=‘00001’;
ELSE
SET @項次 = RIGHT(‘0000’ + CAST(CAST(@項次 AS INT)+1 AS varchar),5);

INSERT INTO dbo.T_B74B(單號,項次)
VALUES (@單號,@項次);
END

——————————————————
— 更新(直接寫,不用動態 SQL)
UPDATE dbo.T_B74B
SET
工程項次 = ISNULL(@工程項次, 工程項次),
項目說明 = ISNULL(@項目說明, 項目說明),
單位 = ISNULL(@單位, 單位),
數量 = ISNULL(@數量, 數量),
單價 = ISNULL(@單價, 單價),
複價 = ISNULL(@複價, 複價),
牌價 = ISNULL(@牌價, 牌價),
折數 = ISNULL(@折數, 折數),
類型 = ISNULL(@類型, 類型),
備註 = ISNULL(@備註, 備註),
品牌 = ISNULL(@品牌, 品牌),
項目說明_2 = ISNULL(@項目說明_2, 項目說明_2),
工作表多頁 = ISNULL(@工作表多頁, 工作表多頁),
AI = ISNULL(@AI, AI),
cRow = ISNULL(@cRow, cRow)
WHERE 單號=@單號 AND 項次=@項次;

END


✅ 你這版改善點(只講重點)

  • ✔ 修正 @cRow bug
  • ✔ 拿掉 EXEC(@cSQL)
  • ✔ 防 ' 爆炸問題(因為不用字串拼接了)
  • ISNUMERIC → TRY_CONVERT
  • ✔ UPDATE 改成原生寫法(效能↑ 穩定↑)

就這樣,沒有多餘廢話。
如果你下一步要「改成多筆版」,再講。

UPDATE T SET T.工程項次 = ISNULL(REPLACE(REPLACE(I.工程項次, ‘.000’, ”), ‘.00’, ”), T.工程項次), T.項目說明 = ISNULL(I.項目說明, T.項目說明), T.單位 = ISNULL(I.單位, T.單位), T.代號 = ISNULL(I.代號, T.代號), T.數量 = CASE WHEN I.數量>0 THEN I.數量 ELSE T.數量 END, T.單價 = CASE WHEN I.單價>0 THEN I.單價 ELSE T.單價 END, T.牌價 = CASE WHEN I.牌價>0 THEN I.牌價 ELSE T.牌價 END, T.折數 = CASE WHEN I.折數>0 THEN T.折數 ELSE T.折數 END, T.類型 = ISNULL(I.類型, T.類型), –T.備註 = ISNULL(I.備註, T.備註), T.品牌 = CASE WHEN I.品牌 IS NULL THEN T.品牌 WHEN UPPER(I.品牌) = ‘KURRENT’ THEN ‘Kurrent’ WHEN EXISTS (SELECT 1 FROM dbo.vi_B765 V WHERE V.品牌 = I.品牌) THEN I.品牌 ELSE ‘*’ END, T.項目說明_2 = ISNULL(dbo.空白轉連接(dbo.全形轉半形(I.項目說明_2)), T.項目說明_2), T.工作表多頁 = ISNULL(I.工作表多頁, T.工作表多頁), –T.AI = ISNULL(I.AI, T.AI), T.cRow = ISNULL(I.cRow, T.cRow) FROM dbo.T_B74B T INNER JOIN INSERTED I ON T.單號 = @單號 AND T.項次 = @項次; 為何 ‘代號’ 無法更新

直接講原因👇

❌ 問題在這行 JOIN

INNER JOIN INSERTED I
ON T.單號 = @單號 AND T.項次 = @項次

👉 你根本沒用 I 的欄位來 JOIN

等於:

  • 跟 INSERTED 沒關聯
  • 只是用「固定變數」去找 T
  • SQL Server 會抓到一筆 I(甚至不確定哪一筆)

👉 結果:

  • I.代號 很可能是 NULL 或錯筆
  • ISNULL(I.代號, T.代號) → 永遠變回 T.代號
    ➡️ 看起來就像「代號沒更新」

✅ 正確寫法

👉 用 INSERTED 來對應

INNER JOIN INSERTED I
ON T.單號 = I.單號
AND T.項次 = I.項次

⚠️ 再補一個你會踩的點

T.代號 = ISNULL(I.代號, T.代號)

👉 如果 I.代號 = ”(空字串)
這行還是會更新成空字串

👉 如果你要「空值也不要更新」,要改:

T.代號 = CASE
WHEN I.代號 IS NULL OR I.代號 =
THEN T.代號
ELSE I.代號
END

⚠️ 你這行也是錯的(順便幫你抓)

T.折數 = CASE WHEN I.折數>0 THEN T.折數 ELSE T.折數 END

👉 不管怎樣都 = T.折數
➡️ 永遠不會更新

應該是:

T.折數 = CASE WHEN I.折數>0 THEN I.折數 ELSE T.折數 END

✅ 結論(很簡單)

你不是「代號不能更新」
👉 是你 JOIN 寫錯,導致抓不到正確的 INSERTED 資料

改這行就好了:

ON T.單號 = I.單號 AND T.項次 = I.項次
個人頭像照片

By 伍芳左

MIS, ERP Pro... RHCE Member (7.2)

發表迴響