2012-04-30 8 views
7

में अपडेट किया गया है, मुझे नहीं पता कि यह कहां से शुरू होगा या यह कैसे काम करेगा और मुझे आशा है कि किसी के पास कोई विचार या सिद्ध विधि हो।एक क्वेरी कैसे बनाएं, जो केवल एक डेटा प्राप्त करता है जिसे तालिका

मैं जो करने की कोशिश कर रहा हूं उसका एक उदाहरण दिखाने के लिए, मैंने एक संग्रहित प्रक्रिया बनाई है जो एक लिंक तालिका से रिकॉर्ड प्राप्त करके स्थानीय तालिका में अद्यतन या INSERT नए रिकॉर्ड बनाता है। संग्रहीत प्रक्रिया नए रिकॉर्ड को अद्यतन और सम्मिलित करने के लिए SQL सर्वर में एक नौकरी के रूप में चलती है।

मेरा प्रश्न है: क्या स्थानीय तालिका में डेटा पूछने का कोई तरीका है ताकि शुरुआत में मैं सभी रिकॉर्ड प्राप्त कर सकूं लेकिन केवल नए रिकॉर्ड प्राप्त किए गए हैं या पुराने रिकॉर्ड अपडेट किए गए हैं?

मैं लगातार सभी रिकॉर्ड प्राप्त नहीं करना चाहता, केवल नए रिकॉर्ड जोड़े गए या रिकॉर्ड अपडेट किए गए।

क्या यह संभव है?

CREATE PROCEDURE sp_UPDATE_PHONE_RECORDS 
AS 
BEGIN 
MERGE dbo.PHONE_REC AS Target 
USING (SELECT MEMBER_ID 
     ,HOME_PHONE = dbo.udf_StdPhoneFmt(HOME) 
     ,CELL_PHONE = dbo.udf_StdPhoneFmt(CELL) 
     ,WORK_PHONE = dbo.udf_StdPhoneFmt(WORK) 

FROM PHONE WHERE MEMBER_ID IS NOT NULL) AS SOURCE 

ON (Target.MEMBER_ID = SOURCE.MEMBER_ID) 

WHEN MATCHED THEN 

    UPDATE SET Target.HOME_PHONE = Source.HOME_PHONE,Target.CELL_PHONE = Source.CELL_PHONE, 
    Target.WORK_PHONE = Source.WORK_PHONE 

WHEN NOT MATCHED BY TARGET THEN 
    INSERT (MEMBER_ID, HOME_PHONE, CELL_PHONE ,WORK_PHONE) 

    VALUES (Source.MEMBER_ID, Source.HOME_PHONE, Source.CELL_PHONE, Source.WORK_PHONE); 
END 
GO 

यह संभव है:

यहाँ संग्रहीत प्रक्रिया मैं स्थानीय फोन के डेटा को अपडेट करने के लिए एक उदाहरण के रूप में बनाया एवेन्यू है?

सभी को धन्यवाद!

+1

यह की तरह लगता है का उपयोग कर सकते [ एसक्यूएल सर्वर प्रतिकृति] (http://msdn.microsoft.com/en-us/library/ms151198.aspx) इस –

उत्तर

6

हम आम तौर पर स्रोत तालिका में दो दिनांक/समय फ़ील्ड जोड़ते हैं, जैसे Source.LastModifiedOn और Source.CreatedOn।

फिर जब नौकरी लक्ष्य तालिका को अपडेट करने के लिए चलाती है तो आप कह सकते हैं कि मुझे सभी स्रोत प्राप्त करें। लास्टमोडाइफाइडऑन और सोर्स। तैयार की गई पंक्तियों के आखिरी बार जब पंक्तियां चलती हैं और पंक्तियों के आधार पर आपके अपडेट/आवेषण करती हैं।

बेशक आपको यह सुनिश्चित करना होगा कि Source.LastModifiedOn और Source.CreatedOn सही तरीके से सेटअप हैं।

+1

के लिए सही उपकरण है यह एक दिलचस्प दृष्टिकोण है। :) एक बार फिर धन्यवाद! – Asynchronous

4

मैं $action स्तंभ के साथ OUTPUT clause का प्रयोग करेंगे:

DECLARE @Target TABLE 
(
    Id INT NOT NULL, 
    Value VARCHAR(10) NULL 
); 
INSERT @Target 
VALUES (1, 'A'), (2, NULL), (3, NULL);  
DECLARE @Source TABLE 
(
    Id INT NOT NULL, 
    Value VARCHAR(10) NULL 
); 
INSERT @Source 
VALUES (2, 'B'), (4, 'D'), (5, 'E'); 
DECLARE @AffectedRows TABLE 
(
    MergeAction  NVARCHAR(10) NOT NULL, 
    Old_Id   INT NULL, 
    Old_Value  VARCHAR(10) NULL, 
    New_Id   INT NULL, 
    New_Value  VARCHAR(10) NULL 
); 

MERGE @Target t 
USING @Source s ON t.Id = s.Id 
WHEN MATCHED THEN 
     UPDATE SET Value = s.Value 
WHEN NOT MATCHED THEN 
     INSERT (Id, Value) VALUES (s.Id, s.Value) 
OUTPUT $action, deleted.Id, deleted.Value, inserted.Id, inserted.Value 
     INTO @AffectedRows(MergeAction, Old_Id, Old_Value, New_Id, New_Value); 

SELECT * FROM @Target; 
SELECT * FROM @AffectedRows; 

परिणाम:

Id Value 
-- ----- 
1 A 
2 B <-- updated row 
3 NULL 
4 D <-- inserted row 
5 E <-- inserted row 

MergeAction Old_Id  Old_Value New_Id  New_Value 
----------- ----------- ---------- ----------- --------- 
INSERT  NULL  NULL  4   D 
INSERT  NULL  NULL  5   E 
UPDATE  2   NULL  2   B 
+1

मैं आपके उदाहरण के साथ काम करने जा रहा हूं और फीडबैक के साथ वापस लौटना चाहता हूं, अगर इसे अन्य प्रश्न हैं तो इसे उत्तर के रूप में चिह्नित नहीं करना चाहते हैं। लेकिन जवाब देने के लिए अपना समय लेने के लिए धन्यवाद। :) – Asynchronous

+0

@UnaverageGuy: यदि आपके कोई प्रश्न हैं, तो बेझिझक पूछें। अगर मुझे जवाब पता है, तो मैं आपकी मदद करूंगा। –

0

आप अपने स्थानीय मेज पर एक उत्प्रेरक है जो जब एक अद्यतन या डालने के लिए उस पर किया जाता है को सक्रिय कर देगा लिख ​​सकते हैं। ट्रिगर तर्क के एक हिस्से के रूप में आपको उन अद्यतन या नए सम्मिलित रिकॉर्ड्स को एक अस्थायी तालिका में डालना होगा। यह सबसे आसान तरीका है जहां आप स्थानीय परिवर्तन में अपने परिवर्तनों का रिकॉर्ड रख सकते हैं।

0

यह मूलतः RDotLee's answer की भिन्नता है, लेकिन यह एक वैकल्पिक दृष्टिकोण है कि मैं कभी कभी का उपयोग जब मैं वास्तविक दिनांक/समय जब रिकॉर्ड बनाया गया था के बारे में परवाह नहीं है:

मैं सिर्फ एक bit क्षेत्र कहा जाता जोड़ने modified डिफ़ॉल्ट मान के साथ 1.
यदि तालिका में कोई नई पंक्ति डाली जाती है, modified स्वचालित रूप से 1 पर सेट हो जाती है।
यदि कोई मौजूदा पंक्ति अपडेट की गई है, तो मुझे यह सुनिश्चित करना होगा कि modified भी 1 पर सेट है।

इस तरह, नौकरी को केवल modified = 1 के साथ सभी पंक्तियों की खोज करने की आवश्यकता है।
नौकरी अंतिम बार निष्पादित होने पर दिनांक/समय का ट्रैक रखने की आवश्यकता नहीं है।

जब कार्य सफलतापूर्वक मार डाला गया था, आखिरी बात यह है modified क्षेत्र सभी पंक्तियों में "रीसेट करने" है: कम काम

update TheTable set modified = 0 

IMO, इस दृष्टिकोण है, जब तुम सिर्फ परवाह के बारे में कि पिछले नौकरी के चलते पंक्तियों को संशोधित किया गया था, लेकिन नहीं जब उन्हें संशोधित किया गया था।

लेकिन यह RDotLee के "LastModifiedOn/CreatedOn" दृष्टिकोण के रूप में ही नुकसान है - आप यह सुनिश्चित करें कि मेज पर प्रत्येक और हर अद्यतन वास्तव में 1 करने के लिए modified स्तंभ सेट करने की जरूरत है, तो आप केवल इस का उपयोग कर सकते हैं जब आप में हैं तालिका में लिखने वाले सभी कोड का नियंत्रण।

+0

ठीक है, मुझे एक समाधान मिला जो काम करता है, सुनिश्चित नहीं है कि यह सबसे अच्छा है, यह यहां पोस्ट किए गए विचारों का संयोजन है। मैंने जो किया वह स्थानीय तालिका पर TIME_STAMP कॉलम बना था। जब भी रिकॉर्ड अपडेट होता है या जब नए रिकॉर्ड डाले जाते हैं तो यह रिकॉर्ड्स (पंक्ति) में SMALLDATETIME जोड़ता है। अब मैं पिछले 24 घंटों में या इस समय के बीच और TIME_STAMP का उपयोग कर रिकॉर्ड किए गए रिकॉर्ड पर स्थानीय तालिका बेस से पूछताछ कर सकता हूं। मैं यहां कोडित पोस्ट कैसे पोस्ट कर सकता हूं? – Asynchronous

+0

@UnaverageGuy क्या आपका मतलब टाइमस्टैम्प है? यह एक छोटा सा समय नहीं है। और मैंने इसे 3 घंटे पहले उत्तर के रूप में पोस्ट किया था। – Paparazzi

+0

नहीं मैंने स्थानीय तालिका पर एक कॉलम बनाया और कॉलम TIME_STAMP नाम दिया, डेटाटाइप smalldatetime है। मुझे अब यह जानने की ज़रूरत है कि मैं इस समय और उस समय के बीच सभी रिकॉर्ड डालने या अपडेट करने के लिए TIME_STAMP कॉलम में डेटाटाइम का उपयोग करके स्थानीय तालिका से कैसे पूछूं। – Asynchronous

0

टाइमस्टैम्प

टाइमस्टैम्प पर वृद्धि और डालने या अद्यतन किया गया है।

मास्टर पर यह एक टाइमस्टैम्प बनाने के लिए और दास पर यह एक बाइनरी (8)

select [timeStampSlave].* 
from [timeStampSlave] 
join [timeStampMaster] 
on [timeStampSlave].[ID] = [timeStampMaster].ID 
and [timeStampSlave].[timeStamp] < [timeStampMaster].[timestamp] 

सर्वर पर क्वेरी करने के लिए आप निम्न सिंटैक्स

[MasterSever].[test].[dbo].[timeStampMaster] 
संबंधित मुद्दे