2010-08-26 10 views
22

मैं मेज है Tbमैं SQL सर्वर पर किसी ट्रिगर में INSERT के मानों को कैसे संपादित कर सकता हूं?

ID | Name | Desc 
------------------------- 
1 | Sample | sample desc 

मुझे लगता है कि उदाहरण के लिए डालने Desc का मूल्य बदल जाएगा, सम्मिलित करें पर ट्रिगर बनाने के लिए चाहते हैं:

INSERT INTO Tb(Name, Desc) VALUES ('x', 'y') 

ID | Name | Desc 
------------------------- 
1 | Sample | sample desc 
2 | x  | Y edited 
में परिणाम होगा

ऊपर के उदाहरण मैं डालने Desc का मूल्य हो गया अपरकेस और एक करने के लिए इसे बदल अंत में edited dded।

मैं क्या जरूरत है, Desc जाता है कि डाला जा रहा हो और इसे संशोधित है यही कारण है कि।

मैं यह कैसे कर सकता हूं?

यह एक अद्यतन के साथ डालने के बाद इसे संभाल करने के लिए बेहतर है? या INSTERAD के INSTEAD के साथ एक ट्रिगर करें और तालिका संरचना में हर बार इसे संशोधित करें?

+1

क्या आप इसे अलग तरीके से नहीं कर सकते? मैं व्यक्तिगत रूप से नफरत करता हूं जब मुझे डेटा पर अजीब चीजें दिखाई देती हैं और मुझे अंत में एहसास होता है कि एक भूत ट्रिगर कुछ सामान कर रहा था –

+0

मैं उस कोड से आने वाली किसी समस्या को ठीक करने के लिए इसका उपयोग करूंगा जो मेरे पास पहुंच नहीं है। यह किसी आइटम के 'यूआरएल' को सम्मिलित करता है, लेकिन यह उच्चारण और विशेष पात्रों को नहीं हटाता है, मैं एक ट्रिगर कर दूंगा जो मेरे लिए करता है। – BrunoLM

+1

यह इतना कठिन अवधारणा नहीं है और यह मेरे दिमाग पर जोर देता है कि माइक्रोसॉफ्ट ऐसी सरल कार्यक्षमता प्रदान नहीं कर सकता है जैसे ओरेकल में जहां आप संपादन करके सम्मिलित करने से पहले किसी भी मूल्य को संशोधित कर सकते हैं: नए मान। यानी अगर मैं हमेशा उन्हें उपयोगकर्ता नाम डालने से पहले ऊपरी भाग में रखना चाहता हूं (मान लीजिए कि मैं इसे किसी कारण से कोड में नहीं कर सकता), तो आपके पास पहले से सम्मिलित ट्रिगर हो सकता है जो: NEW.username: = UPPER (: NEW.username)। SQL सर्वर में हालांकि, आप अंतर्निहित अस्थायी तालिका में मानों के बराबर नहीं कर सकते हैं, और वह वास्तव में बेकार है। – Jim

उत्तर

30

डालने के बाद ट्रिगर का उपयोग करें। प्राथमिक कुंजी पर छद्म तालिका से Tb से जुड़ें। फिर desc के मानों को अद्यतन करें। कुछ की तरह: (लेकिन संकलन नहीं कर सकते हैं)

CREATE TRIGGER TbFixTb_Trg 
ON Tb 
AFTER INSERT 
AS 
BEGIN 
    UPDATE Tb 
    SET DESC = SomeTransformationOf(i.DESC) 
    FROM Tb 
    INNER JOIN inserted i on i.Id = Tb.Id 
END 
GO 

के बाद डालने हुआ है यह ट्रिगर होता है, लेकिन इससे पहले कि insert बयान पूरा करती है। इसलिए लक्ष्य तालिका में नए, गलत मान पहले से ही रखे गए हैं। कॉलम जोड़े, हटाए गए इत्यादि के रूप में इस ट्रिगर को बदलने की आवश्यकता नहीं होगी।

कैविट ट्रिगर आग के बाद ईमानदारी बाधाओं को लागू किया जाता है। इसलिए आप डीईएससी के उचित रूप को लागू करने के लिए चेक बाधा नहीं डाल सकते हैं। क्योंकि इससे ट्रिगर से कुछ भी ठीक करने का मौका मिलने से पहले कथन विफल हो जाएगा। (कृपया इसे पर भरोसा करने से पहले इस पैरा की दोबारा जांच करें यह समय हो गया है मैं एक ट्रिगर लिखा है।।)

+0

इसके अलावा, यह समाधान वास्तव में 'OUTPUT' खंड में उपलब्ध डाले गए मानों को नहीं बनाएगा! –

+0

इस संदर्भ में "Trgt" क्या है? – CodenameCain

+1

@CodenameCain एक गलती। 'टीबी' होना चाहिए या खंड से 'टीबी ट्रग' से होना चाहिए। इसे पकड़ने के लिए धन्यवाद। –

3

आप INSTEAD OF चलाता को देखने के लिए चाहते हो सकता है।

CREATE TRIGGER Tb_InsteadTrigger on Tb 
INSTEAD OF INSERT 
AS 
BEGIN 
... 

यह आपको तालिका में जाने से पहले डेटा में हेरफेर करने की अनुमति देगा। ट्रिगर तालिका में डेटा डालने के लिए ज़िम्मेदार है।

24

मुझे यकीन है कि जहां अपनी वर्णन के लिए वास्तविक नया मान लेने जा रहा नहीं कर रहा हूँ, लेकिन मैं आपको एक और टेबल या कुछ इस तरह से यह हो रही है मान लेते हैं। लेकिन आपके पास शायद इस तरह से ऐसा करने का एक कारण है, इसलिए नीचे एक उदाहरण है कि मैं इसके बारे में कैसे जाऊंगा।

इसके बजाय सम्मिलित करें ट्रिगर का एक क्या आप चाहते हैं कहा जाता है, तो इसकी बजाय डालने की मेज पर क्या हर तर्क आप इसे देने के साथ आग। के रूप में मुझे यकीन है कि तुम कहाँ मूल्य प्राप्त करना चाहते हैं नहीं कर रहा हूँ

CREATE TRIGGER trgUpdateDesc 
ON Tb 
INSTEAD OF INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 
    INSERT INTO Tb (Name, [Desc]) 
    SELECT Name, [Desc] + 'edited' 
    FROM inserted 
END 
GO 

मैं कठिन शब्द कोड जोड़ने के बाद वहाँ में 'संपादित' है, लेकिन आप आसानी से एक चर या किसी अन्य तालिका से एक मूल्य के साथ कि बदल सकते हैं।

ओह भी सुनिश्चित हो [] वर्णन चारों ओर, के रूप में यह एसक्यूएल सर्वर में एक महत्वपूर्ण शब्द है (उतरते के लिए खड़ा है)

आशा डाल कि मदद करता है!

संपादित करें:

आप इसे एक छोटे से अधिक मजबूत बनाने के लिए इतना है कि यह तालिका संरचना पर निर्भर नहीं करता जितना आप सम्मिलित करें ट्रिगर के बाद बस के लिए एक तो जैसे अद्यतन करता है कि क्षेत्र का इस्तेमाल कर सकते हैं।

CREATE TRIGGER [dbo].[trgUpdateDesc] 
    ON [dbo].[Tb] 
    AFTER INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 
    UPDATE Tb 
    SET [Desc] = UPPER(inserted.[Desc]) + ' Edited' 
    FROM inserted INNER JOIN Tb On inserted.id = Tb.id 
END 
+0

मैं डाले गए 'Desc' का मान प्राप्त करना चाहता हूं और इसे संशोधित करना चाहता हूं। मुझे यह कहना चाहिए था। मैं अपना प्रश्न अपडेट करूंगा, उस – BrunoLM

+0

के लिए खेद है यदि मेरी तालिका बदलती है तो क्या होगा? मुझे हर बार ट्रिगर को अपडेट करना होगा? ऐसा करने का कोई और तरीका नहीं है? – BrunoLM

8

अस्थायी तालिका INSTEAD OF INSERT ट्रिगर का उपयोग करते हुए स्पष्ट रूप से सभी असंबंधित तालिका स्तंभ को सूचीबद्ध करने से परहेज करने में मदद कर सकते हैं:

CREATE TRIGGER trgUpdateDesc 
    ON Tb 
    INSTEAD OF INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 
    select * into #tmp from inserted; 
    UPDATE #tmp SET Desc = Desc + 'edited' --where ...; 
    insert into Tb select * from #tmp; 
    drop table #tmp; 
END 

तालिका में नए कॉलम जोड़े जाने पर इस कोड को ठीक करने की आवश्यकता नहीं होगी।

लेकिन some additional overhead of temp tables से सावधान रहें।

यह भी ध्यान दें कि SQL सर्वर थोक डीएमएल संचालन के लिए एक बार आग लगाना और correctly handle multi-row inserts होना चाहिए।

+0

यह निम्न त्रुटि उत्पन्न करता है: तालिका 'टीबी' में पहचान कॉलम के लिए एक स्पष्ट मान केवल तभी निर्दिष्ट किया जा सकता है जब कॉलम सूची का उपयोग किया जाता है और IDENTITY_INSERT चालू होता है। –

+1

@ एंडर्स, मुझे लगता है, यह दृष्टिकोण [पहचान] के साथ असंगत हो सकता है (http://stackoverflow.com/questions/16766963/insert-record-to-sql-table-with-identity-column) कॉलम। लेकिन आप इस कॉलम को ट्रिगर के अंदर '# tmp' तालिका में छोड़ने का भी प्रयास कर सकते हैं। – Vadzim

संबंधित मुद्दे