2 SQL टेबल के बीच सामग्री अंतर कैसे पता करें और सिंक SQL का उत्पादन करें


13

मुझे उन दो तालिकाओं के बीच डेटा में अंतर कैसे पता चलता है जिनके पास सटीक स्कीमा है, और यूनियन परिणाम (डुप्लिकेट के बिना) प्राप्त करने के लिए सिंक्रोनाइज़ेशन एसक्यूएल का उत्पादन कैसे करें?

ये 2 टेबल हैं:

SOURCE01.dbo.Customers (31,022 rows)

TARGET01.dbo.Customers (29,300 rows)

प्रत्येक तालिका का स्कीमा है:

  • [CustomerId] : nvarchar(255)
  • [CustomerSerializedProfile]: nvarchar(max)
  • [CreatedDatetime] : DateTime

जवाबों:


7

पिछले जवाबों में उल्लिखित tablediff और powerhell के अलावा, आप SQL का उपयोग UNION के साथ भी कर सकते हैं। यह कथन 2 समान तालिकाओं में मेल न खाने वाले रिकॉर्ड को खोजने के लिए है:

SELECT MIN(TableName) AS TableName
   ,ID
   ,NAME
   ,lastname
   ,Address
   ,City
FROM (
SELECT 'Table A' AS TableName
    ,Customers.id
    ,Customers.NAME
    ,Customers.lastname
    ,Customers.Address
    ,Customers.City
FROM Customers

UNION ALL

SELECT 'Table B' AS TableName
    ,CustomersOld.id
    ,CustomersOld.NAME
    ,CustomersOld.lastname
    ,CustomersOld.Address
    ,CustomersOld.City
FROM CustomersOld
) tmp
GROUP BY ID
   ,NAME
   ,lastname
   ,Address
   ,City
HAVING COUNT(*) = 1
ORDER BY id;

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

और अंतिम, लेकिन कम से कम, आप SQL डेटा तुलना उपकरण का उपयोग नहीं कर सकते हैं - ApexSQL डेटा डिफ , सभी सिंक्रनाइज़ेशन विकल्प सेट करने के लिए, विभिन्न नामों के साथ तालिकाओं और स्तंभों को मैप करें, GUI में तुलना के लिए अपनी खुद की कुंजी बनाएं। आप इसे अनअटेंडेड चलाने के लिए शेड्यूल कर सकते हैं और आपको बस इतना करना है कि सुबह SQL सर्वर जॉब हिस्ट्री चेक करें। यदि आपको इन विकल्पों के बारे में अधिक जानकारी चाहिए, तो मैं इस लेख को पढ़ने की सलाह देता हूं: http://solutioncenter.apexsql.com/automatically-compare-and-synchronize-sql-server-data/


6

कुछ आश्चर्यजनक रूप से किसी ने यह उल्लेख नहीं किया है कि यह अभी तक SQL सर्वर डेटा टूल्स में बनाया गया है। उदाहरण के लिए Redgate के साथ तुलना करने पर कार्यक्षमता बुनियादी है।

एक संदर्भ डेटाबेस में डेटा के साथ एक या एक से अधिक तालिकाओं में तुलना और सिंक्रनाइज़ डेटा में कुछ विवरण


1
ऐसा इसलिए हो सकता है क्योंकि मई 2014 में, कोई एसएसडीटी नहीं था? अच्छा है कि आपने यह उत्तर दिया है :-)
परिजन शाह

4

मूल उपकरण का उपयोग करना:

tablediff : tablediff उपयोगिता स्रोत तालिका में तालिका के तालिका में डेटा की तुलना करती है।

शक्तियां: तुलना-वस्तु आपको वह हासिल करने की अनुमति देती है। यहाँ एक अच्छा उदाहरण है

तृतीय पक्ष:

रेडगेट स्कीमा और डेटा की तुलना। आप चीजों को स्वचालित करने के लिए पावरशेल और स्कीमा / डेटा का उपयोग भी कर सकते हैं।


3

मैंने हाल ही में एक समान उद्देश्य के लिए इसका उपयोग किया है:

select
    s.*
    ,t.*
from SOURCE01.dbo.Customers as s
full outer join TARGET01.dbo.Customers as t
    on s.CustomerId = t.CustomerId
where s.CustomerSerializedProfile <> t.CustomerSerializedProfile
or s.CreatedDatetime <> t.CreatedDatetime
or s.CustomerId is NULL
or t.CustomerId is NULL;

यह प्राथमिक कुंजी के सुसंगत होने पर निर्भर करता है। लेकिन आप सभी के बाद कुछ लगातार होना चाहिए। ऊपर की तरह कोड उत्पन्न करने के लिए एक मेटा स्क्रिप्ट अपेक्षाकृत लिखना आसान है और कई-स्तंभ तालिकाओं की तुलना करना आसान बनाता है।

तुल्यकालन के लिए के रूप में आप source left join targetऔर target left join sourceफिर, तय करना होगा कि आप प्रत्येक के परिणाम के साथ क्या करना चाहते हैं।


2

यह आपको दो तालिकाओं के बीच अंतर देना चाहिए, फिर आप ए को बी या इसके विपरीत से अंतर डालने के लिए एक सम्मिलित क्वेरी में लपेट सकते हैं।

SELECT A.CustomerId, A.CustomerSerializedProfile, A.CreatedDatetime
  FROM SOURCE01.dbo.Customers A
 WHERE NOT EXISTS (SELECT B.ID
                 FROM TARGET01.dbo.Customers
                WHERE B.CustomerId= A.CustomerId
                  AND B.CustomerSerializedProfile= A.CustomerSerializedProfile
                  AND B.CreatedDatetime= A.CreatedDatetime)

1

हमारे एक निशुल्क उपकरण में टेबलडिफ़ के लिए एक पूर्ण इंटरफ़ेस है:

http://nobhillsoft.com/Diana.aspx

इसके अलावा, हमारे DB तुलना उपकरण की जाँच करें। यह केवल एक ही ऐसा डेटा है जो असीमित मात्रा में डेटा की तुलना करता है (दूसरों में से लाखों और लाखों रिकॉर्ड कर सकते हैं) ... इसलिए जब तक आप 2 सर्वरों के बीच तुलना कर रहे हैं जो जुड़े हुए हैं

http://nobhillsoft.com/NHDBCompare.aspx

(हमने थ्री पार्टी प्रोडक्ट्स के लिए इस थ्रेड में अन्य लिंक देखे ताकि हमें विश्वास हो जाए कि इसका उल्लेख हमारा है ... pls हमें बताएं कि क्या यह नहीं है)


2
AFAIK यह तब तक वैध है जब तक कि यह एक वास्तविक प्रश्न के ऑनटॉप उत्तर के रूप में हो और आपके पास उत्पाद के साथ संबंध हो। तो सोचा होगा ठीक है।
मार्टिन स्मिथ

1

यदि दोनों तालिकाओं में समान प्राथमिक कुंजियाँ हैं, तो आप स्रोत और लक्ष्य तालिकाओं की तुलना करने के लिए नीचे दी गई रणनीति का उपयोग कर सकते हैं: (मैंने एक तारांकित के साथ समग्र कुंजी कॉलम चिह्नित किया है)

with src as (select someCol1*, 
                    someCol2*, 
                    someCol3, 
                    someCol4, 
                    someCol5
             from src_table),

tgt as (select someCol1NameCouldDiffer* as someCol1, 
               someCol2*, 
               someCol3, 
               someCol4, 
               someCol5
        from tgt_table),

--Find which keys have at least 1 non-key column difference:

diffs as (select someCol1, 
                 someCol2 
          from (select all 5 columns 
                from src 
                **union** 
                select all 5 columns 
                from target ) 
           **group by** someCol1, someCol2 
           **having count(*)>1** 

--Reselect all columns you wish to compare from src union target, 
--joining on the keys from "diffs" above to show only records which 
--have data differences.

select * 
from (select all 5 columns 
      from src 
      union 
      select all 5 cols 
       from tgt) t1 
join diffs on t1.someCol1 = diffs.someCol1 
           and t1.someCol2 = diffs.someCol2 
**order by ** someCol1, someCol2 desc

यह काम करता है क्योंकि संघ स्पष्ट रूप से अलग रिकॉर्ड लौटाता है। तो स्रोत में किसी भी पंक्ति (कुछ कुंजी द्वारा पहचाने गए) के लिए आप लक्ष्य में बिल्कुल मेल खाने की अपेक्षा करते हैं, आप src के संघ और किसी भी दिए गए कुंजी के लिए 1 पंक्ति वापस करने के लिए लक्ष्य की उम्मीद करेंगे। इस प्रकार आप उपरोक्त कार्यनीति का उपयोग यह पता लगाने के लिए कर सकते हैं कि कौन-सी कुंजियाँ एकाधिक पंक्तियों वाले संघ परिणाम देती हैं, फिर src संघ लक्ष्य को फिर से क्वेरी करें, (इस बार केवल अंतर तालिका के साथ जुड़कर अंतरों का चयन करते हुए) उन सभी स्तंभों का चयन करें जिनकी आप इच्छा रखते हैं तुलना करते हुए, कुंजी की रचना करने वाले कॉलम द्वारा ऑर्डर करना, और आप देखेंगे कि वास्तव में कौन से कॉलम बेमेल हैं। स्रोत और लक्ष्य में स्तंभ नामों पर ध्यान दें, मेल खाने की जरूरत नहीं है, क्योंकि उन्हें "के रूप में" कथन का उपयोग करके एक-दूसरे के लिए उपनाम दिया जा सकता है।


0

दो समान तालिकाओं के बीच मतभेदों को खोजने के लिए

* का चयन करें
SOURCE01.dbo.Customers से

यूनिअन

चुनें *
TARGET01.dbo.Customers से

छोड़कर

चुनें *
SOURCE01.dbo.Customers से

INTERSECT

चुनें *
TARGET01.dbo.Customers से


संचालन के आदेश के कारण पहले प्रदर्शन किया जाता है जो आपको केवल उन पंक्तियों का डेटासेट देगा जो दोनों तालिकाओं में मौजूद हैं। दूसरा UNION किया जाता है जो आपको डुप्लिकेट के बिना दोनों तालिकाओं से सभी पंक्तियाँ देता है। अंत में, EXCEPT प्रदर्शन किया जाता है जो आपके UNION (दोनों तालिकाओं की सभी पंक्तियों) को हटाता है INTERSECT डेटासेट जो दोनों तालिकाओं में पंक्तियाँ है। यह आपको केवल एक पंक्तियों वाली डेटासेट के साथ छोड़ता है जो किसी एक तालिका में मौजूद है लेकिन दूसरे में नहीं है। यदि आपका डेटासेट खाली आता है तो सभी पंक्तियाँ तालिकाओं के बीच समान होती हैं।



https://docs.microsoft.com/en-us/sql/t-sql/language-elements/set-operators-except-and-intersect-transact-sql


सुनो! मुझे लगता है कि यदि आप मूल प्रश्न से तालिका नामों का उपयोग करते हैं तो आपका उत्तर बेहतर होगा!
एंथोनी जेनोविसे

0

मुझे एक समान समस्या थी और समस्या को हल करने के लिए SQL 'EXCEPT' कमांड का उपयोग किया। EXCEPT कमांड दो सेलेक्ट स्टेटमेंट लेता है और जो पंक्तियाँ पहले SELECT स्टेटमेंट (लेफ्ट) द्वारा लौटा दी जाती हैं और सेकंड (राइट) सेलेक्ट स्टेटमेंट द्वारा नहीं लौटती हैं।

SELECT * from table1 where x,y,z 
EXCEPT
SELECT * from table2 where a,b,c

पुनश्च: सेलेक्ट स्टेटमेंट द्वारा लौटाए गए दोनों टेबल के स्कीमा का मिलान होना चाहिए।

अधिक स्पष्टता के लिए, यहां जाएं: ट्यूटोरियल प्वाइंट पेज


0
/*
Compare master table data on 2 servers (
1. Change server name
2. Set RaceDate (@racedate) with the >, < ,= >= operator 
 before you run)

 --KNOWN ISSUES
 1. Tables need PKs

*/
SET NOCOUNT ON

--Destination Server Details
DECLARE @destServ nvarchar(40)='[sql\inst23]'    --required             -- If local instance, leave the string empty 
DECLARE @destdb nvarchar(40)='DBName'         --required        
DECLARE @destSchema nvarchar(40)='dbo'        --required        
DECLARE @destTable  nvarchar(40)='TableName'    --required      

-- Source Server Details
DECLARE @SourServ nvarchar(40)='[sql\inst07]'   --required      
DECLARE @Sourdb nvarchar(40)='DBonRemoteServer'  --required     
DECLARE @SourSchema nvarchar(40)='dbo'          --required      
DECLARE @SourTable  nvarchar(40)='TableName'      --required                                -- TableName format 'MyTable'

DECLARE @WHERE nvarchar(400) = 'WHERE 1=1'

DECLARE @Clause nvarchar(400)= 'AND Id > 201808201500000'       --Choose a Predicate to limit data --Start with AND . e.g: 'AND Date > ''20180801'' '

SELECT @WHERE = @WHERE + @Clause

DECLARE @randomtablesuffix nvarchar(5)
SELECT @randomtablesuffix= SUBSTRING(CAST(NEWID() as nvarchar(255)),1,5)


declare @v nvarchar(max), @sql nvarchar(max), @retval nvarchar(max) , @ParamDef nvarchar(400)

--GET Columns List as varchar Columns for HASHBYTES to compare
SELECT @sql='SELECT @vv= COALESCE(@vv,'''')+''CAST(ISNULL(''+ COLUMN_NAME  + '',0) as VARCHAR(''+ 
        CASE WHEN DATA_TYPE IN (''varchar'',''nvarchar'') THEN CAST(CHARACTER_MAXIMUM_LENGTH as varchar(5)) ELSE ''60 '' END +'')) + ''
from '+ @destdb + '.INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='+ QUOTENAME(@destTable,'''') + ''

SET @ParamDef = N'@vv nvarchar(max) OUTPUT'
EXEC sp_executesql @sql, @ParamDef, @vv=@v OUTPUT;

SELECT @v= SUBSTRING(@v,0,LEN(@v))

--Keys to JOIN
DECLARE @pkeylistJoinOUT nvarchar(4000)=''
SET @sql='SELECT @pkeylistJoin = ISNULL(@pkeylistJoin,'''') + '' a.''+ QUOTENAME(COLUMN_NAME) + ''=b.''+ QUOTENAME(COLUMN_NAME) + '' AND'' 
    FROM '+@destdb+'.[INFORMATION_SCHEMA].[KEY_COLUMN_USAGE]
    WHERE TABLE_NAME='+ QUOTENAME(@destTable,'''') + ' ORDER BY ORDINAL_POSITION'

SET @ParamDef = N'@pkeylistJoin nvarchar(max) OUTPUT'
EXEC sp_executesql @sql, @ParamDef, @pkeylistJoin=@pkeylistJoinOUT OUTPUT;  

SELECT @pkeylistJoinOUT = REPLACE(REPLACE(REVERSE( SUBSTRING(REVERSE(@pkeylistJoinOUT), CHARINDEX(']', REVERSE(@pkeylistJoinOUT)), LEN(@pkeylistJoinOUT)) ),']',''),'[','')


--Get Column List 

DECLARE @ColumnListOut nvarchar(max)=''
SET @sql='SELECT  @ColumnList=ISNULL(@ColumnList,'''') + COLUMN_NAME + '',''  FROM '+@destdb +'.[INFORMATION_SCHEMA].[COLUMNS] WHERE TABLE_NAME='+QUOTENAME(@destTable,'''')+ ' ORDER BY ORDINAL_POSITION'

SET @ParamDef = N'@ColumnList nvarchar(max) OUTPUT'
EXEC sp_executesql @sql, @ParamDef, @ColumnList=@ColumnListOut OUTPUT;  


SET @ColumnListOut=SUBSTRING(@ColumnListOut,0,LEN(@ColumnListOut))

--Now Compare

SELECT @sql='

SELECT a.* INTO ##_destissues'+@randomtablesuffix+' FROM (
SELECT HASHBYTES (''SHA2_512'','+ @v +')HashVal,'+ @ColumnListOut +' FROM '+@destServ+'.'+@destdb+'.'+@destSchema+'.'+@destTable + ' x WITH (NOLOCK) ' + @WHERE + '
)a 
JOIN (
SELECT HASHBYTES (''SHA2_512'','+@v +')HashVal,'+ @ColumnListOut + ' FROM ' +@SourServ +'.'+ @Sourdb+ '.'+@SourSchema+'.'+ @SourTable +' y WITH (NOLOCK)  ' + @WHERE + '
)
b ON '+@pkeylistJoinOUT + ' AND  a.HashVal <> b.HashVal '

--print @sql

exec (@sql)


SELECT @sql='

SELECT b.* INTO ##_sourceissues'+@randomtablesuffix+ ' FROM (
SELECT HASHBYTES (''SHA2_512'','+ @v +')HashVal,'+ @ColumnListOut +' FROM '+@destServ+'.'+@destdb+'.'+@destSchema+'.'+@destTable + ' x WITH (NOLOCK) ' + @WHERE + '
)a 
JOIN (
SELECT HASHBYTES (''SHA2_512'','+@v +')HashVal,'+ @ColumnListOut + ' FROM ' +@SourServ +'.'+ @Sourdb+ '.'+@SourSchema+'.'+ @SourTable +' y WITH (NOLOCK)  ' + @WHERE + '
)
b ON '+@pkeylistJoinOUT + ' AND  a.HashVal <> b.HashVal '


exec (@sql)

--Get Column List for Pivoting
DECLARE @ColumnListOutasVC nvarchar(max)=''

SET @sql='SELECT  @ColumnList=ISNULL(@ColumnList,'''')+  ''CAST(''+ COLUMN_NAME + '' AS VARCHAR(200)) as ''+ COLUMN_NAME + '',''   FROM ' + @destdb+'.[INFORMATION_SCHEMA].[COLUMNS] WHERE TABLE_NAME='+QUOTENAME(@desttable,'''')


SET @ParamDef = N'@ColumnList nvarchar(max) OUTPUT'
EXEC sp_executesql @sql, @ParamDef, @ColumnList=@ColumnListOutasVC OUTPUT;  

SET @ColumnListOutasVC=SUBSTRING(@ColumnListOutasVC,0,LEN(@ColumnListOutasVC))

--Get PKs as VARCHAR Values

DECLARE @pkeylistJoinOUTVC nvarchar(4000)=''

SET @sql='SELECT @pkeylistJoin = ISNULL(@pkeylistJoin,'''') + ''CAST(''+COLUMN_NAME + '' as varchar(200)) as '' + COLUMN_NAME + ''1,''  FROM '+ @destdb+'.[INFORMATION_SCHEMA].[KEY_COLUMN_USAGE]   WHERE TABLE_NAME='+QUOTENAME(@destTable,'''') + '  ORDER BY ORDINAL_POSITION'

SET @ParamDef = N'@pkeylistJoin nvarchar(max) OUTPUT'
EXEC sp_executesql @sql, @ParamDef, @pkeylistJoin=@pkeylistJoinOUTVC OUTPUT;    
SET @pkeylistJoinOUTVC=SUBSTRING(@pkeylistJoinOUTVC,0,LEN(@pkeylistJoinOUTVC))
--SELECT @pkeylistJoinOUTVC





SET @sql='
select  * INTO ##_destissuedetail'+@randomtablesuffix+ ' from(
select '+ @pkeylistJoinOUTVC + ', ' + @ColumnListOutasVC
                + '
from 
##_destissues'+ @randomtablesuffix+ '
)c UNPIVOT
(
Vals for ColNames in ('+@ColumnListOut+')
) d'

EXEC( @sql)


SET @sql='
select  * INTO ##_sourceissuedetail'+@randomtablesuffix+' from(
select '+ @pkeylistJoinOUTVC + ', ' + @ColumnListOutasVC
                + '
from 
##_sourceissues'+ @randomtablesuffix+'
)c UNPIVOT
(
Vals for ColNames in ('+@ColumnListOut+')
) d'

EXEC( @sql)

SELECT 'Tables to look for data are ##_destissuedetail'+@randomtablesuffix +' and  ##_sourceissuedetail ' +@randomtablesuffix

SET @sql='
SELECT * FROM ##_destissuedetail'+@randomtablesuffix+ '
EXCEPT
SELECT * FROM ##_sourceissuedetail' +@randomtablesuffix

EXEC (@sql)

स्क्रिप्ट (जब प्रासंगिक विवरण के साथ प्रदान की गई है) 2 तालिकाओं की तुलना करती है (कहें कि Server1 पर ग्राहक से Server2 पर ग्राहक)।

यदि आप कई स्तंभों वाली तालिका की तुलना कर रहे हैं, लेकिन सटीक बेमेल कॉलम को खोजने के लिए संघर्ष कर रहे हैं तो यह स्क्रिप्ट उपयोगी होगी।

मेरे पास 353 स्तंभों वाली एक तालिका है और मुझे इसकी तुलना दूसरी तालिका से करनी थी और मान लेना चाहिए कि मिलान मेल नहीं खा रहा है और यह स्क्रिप्ट आपको सटीक टपल का पता लगाने में मदद करेगी।


-1

मुझे लगता है कि आपको xSQL डेटा तुलना की कोशिश करनी चाहिए , जो आपके मामले में चाल चलेगी । उदाहरण के लिए मान लें, कि आप निर्दिष्ट करते हैं

SOURCE01.dbo.Customers as the **left table** and
TARGET01.dbo.Customers as the **right table**

जब आप तालिकाओं की तुलना करते हैं, तो तुलनात्मक परिणाम में, आप यह निर्दिष्ट कर सकते हैं कि आप केवल बाईं तालिका के अंतरों को सिंक करना चाहते हैं, जो कि TARGET01.dbo.Customers को उन सभी पंक्तियों में सम्मिलित करने के लिए SQL स्क्रिप्ट उत्पन्न करेगा जो इस तालिका में नहीं हैं लेकिन अस्तित्व SOURCE01.dbo.Customers में (डुप्लिकेट के बिना एक संघ परिणाम हासिल करने)। उम्मीद है की यह मदद करेगा!

प्रकटीकरण: मैं xSQL से संबद्ध हूं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.