2017-04-11 78 views
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)) 
    ) 
+3

問題一就在這裏:「SELECT V_Refno = tgreq_refno FROM inserted」。插入的集合可以包含多行......但此觸發器僅假設一行。所有的觸發器應該總是假設插入/刪除可以有多行,並且在SETS上工作,而不是標量。在更新時,V_Refno將僅包含插入的最後一行的值,例如,如果更新了多行。 – pmbAustin

+0

@pmbAustin \t 謝謝,我已經嘗試了一百萬變化的更新知道問題是在那裏的某個地方,仍然沒有喜悅。之前我嘗試過的批量更新不起作用,那麼神奇的觸摸是什麼?我將更新添加到主線程的末尾。 –

+1

您可能還想在繼續向各地潑灑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 –

回答

0

我終於得到了燈泡瞬間在回家的路上。不要將更新鏈接到插入的表,而只是根據匹配記錄進行批量更新。

對不起,發佈之前沒有得到。漫長的一天。