2009-10-25 19 views
5

मैं नए सॉफ्टवेयर विकसित करते समय मौजूदा डेटाबेस में परिवर्तन कर रहा हूं। वहाँ भी काफी विरासत सॉफ्टवेयर का एक बहुत है कि डेटाबेस काम जारी रखने की जरूरत है कि का उपयोग करता है, यानी मैं मौजूदा डेटाबेस तालिकाओं, procs, आदि को बनाए रखने के लिए करना चाहते हैंअद्यतन ट्रिगर की स्थापना और प्राथमिक कुंजी को अपडेट करना

वर्तमान में मेरे पास है तालिका

 
CREATE TABLE dbo.t_station (
    tx_station_id  VARCHAR(4) NOT NULL, 
    tx_description  NVARCHAR(max) NOT NULL, 
    tx_station_type  CHAR(1)  NOT NULL, 
    tx_current_order_num VARCHAR(20) NOT NULL, 

    PRIMARY KEY (tx_station_id) 
) 

मुझे इस तालिका में एक नया क्षेत्र शामिल करना होगा जो एक संयंत्र (उत्पादन सुविधा) को संदर्भित करता है और tx_current_order_num को दूसरी तालिका में ले जाता है क्योंकि यह सभी पंक्तियों के लिए आवश्यक नहीं है। तो मैं बना लिया है नया टेबल: -

 
CREATE TABLE Private.Plant (
    PlantCode INT   NOT NULL, 
    Description NVARCHAR(max) NOT NULL, 

    PRIMARY KEY (PlantCode) 
) 
CREATE TABLE Private.Station (
    StationId VARCHAR(4) NOT NULL, 
    Description NVARCHAR(max) NOT NULL, 
    StationType CHAR(1)  NOT NULL, 
    PlantCode INT   NOT NULL, 

    PRIMARY KEY (StationId), 

    FOREIGN KEY (PlantCode) REFERENCES Private.Plant (PlantCode) 
) 
CREATE TABLE Private.StationOrder (
    StationId VARCHAR(4) NOT NULL, 
    OrderNumber VARCHAR(20) NOT NULL, 

    PRIMARY KEY (StationId) 
) 

अब, मैं दो स्थानों पर एक ही डेटा है नहीं करना चाहती तो मैं एक दृश्य में dbo.t_station तालिका बदल सकते हैं और करने के लिए ट्रिगर के बजाय प्रदान करने का निर्णय लिया हटाएं, अंदरूनी और अद्यतन करें। कोई समस्या नहीं है [उनमें से अधिकांश] काम कर रहे हैं।

मेरा प्रश्न अद्यतन कुंजी ट्रिगर के इंस्टीटैड का संबंध है, प्राथमिक कुंजी कॉलम (tx_station_id) को अपडेट करना और एकाधिक पंक्तियों के अपडेट।

ट्रिगर ब्लॉक के अंदर, क्या सम्मिलित और हटाए गए [psuedo] तालिकाओं में शामिल होने का कोई तरीका है ताकि मैं 'प्राथमिक कुंजी अपडेट करने से पहले' और 'प्राथमिक कुंजी अपडेट के बाद' जान सकूं? कुछ इस तरह ...

 
UPDATE sta 
    SET sta.StationId = ins.tx_station_id 
    FROM Private.Station AS sta 
     INNER JOIN deleted AS del 
      INNER JOIN inserted AS ins 
       ON ROW_IDENTITY_OF(del) = ROW_IDENTITY_OF(ins) 
      ON del.tx_station_id = sta.StationId 

इस स्तर पर यदि प्राथमिक कुंजी स्तंभ अद्यतन किया जाता है मैं ट्रिगर ब्लॉक कि अद्यतन rollbacks में एक चेक डाल दिया है और वहाँ डाला, या हटाया गया में एक से अधिक पंक्ति है , टेबल।

+1

मुझे उम्मीद थी कि किसी के पास बेहतर जवाब हो सकता है! इस समस्या ने मुझे अतीत में भी परेशान किया है। –

उत्तर

3

संक्षिप्त उत्तर नहीं है।

आप निजी.स्टेशन पर एक सरोगेट कुंजी डाल सकते हैं, और दृश्य के माध्यम से इसका पर्दाफाश कर सकते हैं और मूल्यों के पहले और बाद में पहचानने के लिए इसका उपयोग कर सकते हैं। आपको प्राथमिक कुंजी या विदेशी कुंजी संबंध बदलने की आवश्यकता नहीं होगी, लेकिन आपको दृश्य के माध्यम से कुछ गैर-अद्यतन करने योग्य क्रुफ़्ट का खुलासा करना होगा, ताकि यह छद्म-तालिकाओं में दिखाई दे। उदाहरण:

alter table Private.Station add StationSk int identity(1,1) not null 

नोट, यदि यह चयन * का उपयोग करता है तो यह विरासत एप्लिकेशन को तोड़ सकता है। स्पष्ट डालने कॉलम सूचियों के बिना INSERT कथन ठीक होना चाहिए, यद्यपि।

कि की कमी है, वहाँ डाला जाता है और नष्ट कर दिया, ऐसी है कि ROW_NUMBER() से अधिक (NULLIF (StationId, StationId) द्वारा आदेश) आप दो में शामिल हो जाएगा के बीच कुछ गैर-दस्तावेजी & संगत आदेश हो सकता है, लेकिन मैं था मार्ग लेने में बहुत संकोच न करें। बहुत, बहुत संकोचजनक।

क्या आपने जानबूझकर कैस्केड अपडेट सक्षम नहीं किए हैं? वे उपयोगी होते हैं जब प्राथमिक कुंजी मान अपडेट किए जा सकते हैं। उदाहरण:

CREATE TABLE Private.Station (
    StationId VARCHAR(4) NOT NULL, 
    Description NVARCHAR(max) NOT NULL, 
    StationType CHAR(1)  NOT NULL, 
    PlantCode INT   NOT NULL, 
    PRIMARY KEY (StationId), 
    FOREIGN KEY (PlantCode) REFERENCES Private.Plant (PlantCode) 
     ON UPDATE CASCADE 
     -- maybe this too: 
     -- ON DELETE CASCADE 
) 

किसी के पास बेहतर चाल हो सकती है। रुको और देखो!

+0

हां, सरोगेट कुंजी विचार के बारे में सोचा लेकिन मैं तालिका नाम और कॉलम को ठीक से संरक्षित करना चाहता था। कैस्केडिंग अपडेट्स और डिलीट्स के लिए जो मेरी प्राथमिक चिंता के लिए काम नहीं करेंगे। StationId को पूरे डेटाबेस में संदर्भित किया गया है और मैं यह सुनिश्चित करना चाहता हूं कि संदर्भ तालिका सही, तार्किक, स्टेशन का संदर्भ जारी रखे। – Kepboy

+0

मुझे यह इंगित करना चाहिए कि मैं अपने एकल पंक्ति समाधान से पूरी तरह से नाखुश नहीं हूं, बस सोचा कि मैं पूछूंगा क्योंकि मुझे इन चीजों को जानना अच्छा लगता है। – Kepboy

+0

वर्तमान स्कीमा में t_station.tx_station_id की अनुमति है? यदि नहीं, तो COLUMNS_UPDATED(), रोलबैक के साथ अपडेट के लिए परीक्षण करें और यदि आप किसी भी परिवर्तन का पता लगाते हैं तो त्रुटि उत्पन्न करें। –

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