Реализовать симметричную разницу в SQL Server? - PullRequest
1 голос
/ 16 сентября 2008

Вот проблема, которую я пытался решить на работе. Я не эксперт по базам данных, так что, возможно, это немного второкурсник. Все извинения.

У меня есть заданная база данных D, которая была продублирована на другом компьютере (возможно, сомнительным образом), что привело к созданию базы данных D '. Моя задача - убедиться, что базы данных D и D 'фактически идентичны.

Проблема, конечно же, в том, что на самом деле делать, если это не так. Для этого я подумал о том, чтобы провести симметричную разность для каждой соответствующей таблицы и увидеть различия.

Существует "большое" количество таблиц, поэтому я не хочу запускать каждую симметричную разность вручную. Как мне тогда реализовать симметричную разностную «функцию» (или хранимую процедуру, или что угодно), которая может выполняться в произвольных таблицах без явного перечисления столбцов?

Это работает в Windows, и ваш хедж-фонд взорвется, если вы не выполните его. Удачи.

Ответы [ 5 ]

3 голосов
/ 08 октября 2012

Вы можете достичь этого, сделав что-то вроде этого.

Я использовал функцию для разделения значения через запятую в таблицу для демонстрации.

CREATE FUNCTION [dbo].[Split]
(
    @RowData nvarchar(2000),
    @SplitOn nvarchar(5)
)  
RETURNS @RtnValue table 
(
    Id int identity(1,1),
    Data nvarchar(100)
) 
AS  
BEGIN 
    Declare @Cnt int
    Set @Cnt = 1

    While (Charindex(@SplitOn,@RowData)>0)
    Begin
        Insert Into @RtnValue (data)
        Select 
            Data = ltrim(rtrim(Substring(@RowData,1,Charindex(@SplitOn,@RowData)-1)))

        Set @RowData = Substring(@RowData,Charindex(@SplitOn,@RowData)+1,len(@RowData))
        Set @Cnt = @Cnt + 1
    End

    Insert Into @RtnValue (data)
    Select Data = ltrim(rtrim(@RowData))

    Return
END
GO


DECLARE @WB_LIST varchar(1024) = '123,125,764,256,157';
DECLARE @WB_LIST_IN_DB varchar(1024) = '123,125,795,256,157,789';

DECLARE @TABLE_UPDATE_LIST_IN_DB TABLE ( id varchar(20));
DECLARE @TABLE_UPDATE_LIST TABLE ( id varchar(20));

INSERT INTO @TABLE_UPDATE_LIST
SELECT data FROM dbo.Split(@WB_LIST,',');

INSERT INTO @TABLE_UPDATE_LIST_IN_DB
SELECT data FROM dbo.Split(@LIST_IN_DB,',');


SELECT * FROM @TABLE_UPDATE_LIST
EXCEPT
SELECT * FROM @TABLE_UPDATE_LIST_IN_DB
UNION
SELECT * FROM @TABLE_UPDATE_LIST_IN_DB
EXCEPT
SELECT * FROM @TABLE_UPDATE_LIST;
2 голосов
/ 28 марта 2010

Вот решение. Данные примера взяты из базы данных ReportServer, поставляемой с SSRS 2008 R2, но вы можете использовать ее в любом наборе данных:

SELECT s.name, s.type 
FROM 
(
    SELECT s1.name, s1.type
    FROM syscolumns s1
    WHERE object_name(s1.id) = 'executionlog2'
    UNION ALL 
    SELECT s2.name, s2.type
    FROM syscolumns s2 
    WHERE object_name(s2.id) = 'executionlog3'
) AS s 
GROUP BY s.name, s.type   
HAVING COUNT(s.name) = 1
1 голос
/ 30 мая 2012

SQL Server 2000 Добавлено ключевое слово «EXCEPT», которое практически совпадает с «минусом» Oracle

SELECT * FROM TBL_A WHERE ...
EXCEPT
SELECT * FROM TBL_B WHERE ...
1 голос
/ 16 сентября 2008

Моя первая реакция состоит в том, чтобы предложить дублирование на другую машину снова без сомнений.

Если это не вариант, возможно, некоторые из инструментов, доступных в Красные Ворота , могут сделать то, что вам нужно.

(Я никоим образом не связан с Red Gate, просто помню, как Джоэл упоминал, насколько хороши их инструменты на подкасте.)

0 голосов
/ 16 сентября 2008

Используйте инструменты SQL Compare by Red Gate . Он сравнивает схемы, а инструмент сравнения данных SQL сравнивает данные. Я думаю, что вы можете получить бесплатную пробную версию для них, но вы могли бы также купить их, если это повторяющаяся проблема. Там могут быть с открытым исходным кодом или бесплатные инструменты, как это, но вы могли бы просто получить этот.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...