0
這裏有很多關於觸發器應該如何工作的答案,但我想知道我的獨特之處在於代碼在insert上運行,但是@type變量會得到一個錯誤的答案。如果我使用表引用隔離運行查詢,則會返回正確的答案;它只是作爲觸發的一部分,我得到一個錯誤。爲什麼觸發器中的更新失敗?
查詢的一部分調用一個函數,但這一切都工作時孤立完成,所以我想知道是否有其他東西在我的觸發器導致它失敗,我不知道?
SQL:
ALTER TRIGGER [dbo].[MPH_I_TEST_GROUP_REQUEST_PRINTS]
ON [dbo].[MPH_PRINT_TEST_QUEUE]
FOR INSERT,UPDATE
AS
DECLARE @V_Refno NUMERIC(10)
DECLARE @V_User_Modif VARCHAR(30)
BEGIN
SET @V_User_Modif = suser_sname()
SELECT @V_Refno = tgreq_refno FROM inserted
--> Get details of test type
DECLARE @car_sponts VARCHAR(8000)
DECLARE @type VARCHAR(50)
SET @type = 'blank'
SELECT @car_sponts = CONVERT(VARCHAR(8000),sypro.long_value)
FROM
system_profiles sypro (NOLOCK)
WHERE
sypro.code = 'MPH_CARD_PRT_SPONTS'
AND (sypro.archv_flag = 'N' OR sypro.archv_flag IS NULL)
--> Update type based on tests ordered
SELECT
@type = CASE WHEN COUNT(*) > 0 THEN 'CARDIO' ELSE 'type fail' END --> Does the request belong in a service point noted in system profile MPH_CARD_PRT_SPONTS
FROM
test_group_requests tgreq (NOLOCK)
INNER JOIN
test_form_requests tfreq (NOLOCK) ON tgreq.tgreq_refno = tfreq.tgreq_refno
INNER JOIN
test_requests tereq (NOLOCK) ON tfreq.tfreq_refno = tereq.tfreq_refno
INNER JOIN
test_definitions tstdf (NOLOCK) ON tereq.tstdf_refno = tstdf.tstdf_refno
INNER JOIN
test_locations tstlc (NOLOCK) ON tstlc.tstdf_refno = tstdf.tstdf_refno
WHERE
tgreq.tgreq_refno IN (SELECT tgreq_refno FROM inserted)
AND (tstlc.archv_flag = 'N' OR tstlc.archv_flag IS NULL)
AND tstlc.spont_refno IN
(
SELECT DISTINCT spont.spont_refno FROM service_points spont (NOLOCK) WHERE (spont.archv_flag = 'N' OR spont.archv_flag IS NULL) AND spont.code IN (SELECT Item FROM [dbo].[MPH_PARSELIST](@car_sponts))
)
--> Update test type to print queue
UPDATE mph_print_test_queue
SET mph_print_test_queue.type = 'updated ' + @type
FROM
inserted,mph_print_test_queue
WHERE
mph_print_test_queue.tgreq_refno = inserted.tgreq_refno
END
所以目前所有的記錄得到一個類型的「更新後的類別失敗」即使他們符合「心」的認定標準進行插入/更新。
在此先感謝。菲爾。
試過這個更新還:
UPDATE mph_print_test_queue
SET mph_print_test_queue.type = 'updated cardio'
FROM
inserted,test_group_requests tgreq (NOLOCK)
INNER JOIN
test_form_requests tfreq (NOLOCK) ON tgreq.tgreq_refno = tfreq.tgreq_refno
INNER JOIN
test_requests tereq (NOLOCK) ON tfreq.tfreq_refno = tereq.tfreq_refno
INNER JOIN
test_definitions tstdf (NOLOCK) ON tereq.tstdf_refno = tstdf.tstdf_refno
INNER JOIN
test_locations tstlc (NOLOCK) ON tstlc.tstdf_refno = tstdf.tstdf_refno
WHERE
tgreq.tgreq_refno = inserted.tgreq_refno
AND (tstlc.archv_flag = 'N' OR tstlc.archv_flag IS NULL)
AND tstlc.spont_refno IN
(
SELECT DISTINCT spont.spont_refno FROM service_points spont (NOLOCK) WHERE (spont.archv_flag = 'N' OR spont.archv_flag IS NULL) AND spont.code IN (SELECT Item FROM [dbo].[MPH_PARSELIST](@car_sponts))
)
問題一就在這裏:「SELECT V_Refno = tgreq_refno FROM inserted」。插入的集合可以包含多行......但此觸發器僅假設一行。所有的觸發器應該總是假設插入/刪除可以有多行,並且在SETS上工作,而不是標量。在更新時,V_Refno將僅包含插入的最後一行的值,例如,如果更新了多行。 – pmbAustin
@pmbAustin \t 謝謝,我已經嘗試了一百萬變化的更新知道問題是在那裏的某個地方,仍然沒有喜悅。之前我嘗試過的批量更新不起作用,那麼神奇的觸摸是什麼?我將更新添加到主線程的末尾。 –
您可能還想在繼續向各地潑灑nolock提示之前查看此內容。這比許多人意識到的要難得多。 http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/在你的更新中你確實應該使用ANSI-92風格的連接,他們已經存在了25年。 http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old-style-joins.aspx –