Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 需要SQL Server的比较表实用程序_Sql Server_Sql Server 2005_Comparison_Diff - Fatal编程技术网

Sql server 需要SQL Server的比较表实用程序

Sql server 需要SQL Server的比较表实用程序,sql-server,sql-server-2005,comparison,diff,Sql Server,Sql Server 2005,Comparison,Diff,SQL server的命令行或库“比较表”实用程序,可将全面的差异输出到.Net中的文件 我找不到那样的东西。商业或免费(XSQL Lite适用于我的案例,并且)工具显示网格中的差异,可以导出到CSV。当从命令行运行时,它们还会生成同步SQL脚本。我需要的是一个适合解析的综合报告(XML、HTML)输出,这样我就能够在我的应用程序中显示类似的差异网格(更新每列的旧/新值、添加-行的所有值、删除-行的所有值等等) 因为听起来您只想在应用程序中显示差异,只需编写自己的查询,这并不难,下面是一个示例:

SQL server的命令行或库“比较表”实用程序,可将全面的差异输出到.Net中的文件


我找不到那样的东西。商业或免费(XSQL Lite适用于我的案例,并且)工具显示网格中的差异,可以导出到CSV。当从命令行运行时,它们还会生成同步SQL脚本。我需要的是一个适合解析的综合报告(XML、HTML)输出,这样我就能够在我的应用程序中显示类似的差异网格(更新每列的旧/新值、添加-行的所有值、删除-行的所有值等等)

因为听起来您只想在应用程序中显示差异,只需编写自己的查询,这并不难,下面是一个示例:

DECLARE @TableA table (RowID int, Col1 int, Col2 varchar(5), Col3 datetime)
DECLARE @TableB table (RowID int, Col1 int, Col2 varchar(5), Col3 datetime)
set nocount on
INSERT @TableA VALUES( 1,111,'AAA','1/1/2010')
INSERT @TableA VALUES( 2,222,'BBB','1/1/2010')
INSERT @TableA VALUES( 3,333,'CCC','1/1/2010')
INSERT @TableA VALUES( 4,444,'DDD','1/1/2010')
INSERT @TableA VALUES( 5,555,'EEE','1/1/2010')
INSERT @TableA VALUES( 6,666,'FFF','1/1/2010')
INSERT @TableA VALUES( 7,777,'GGG','1/1/2010')
INSERT @TableA VALUES( 9,888,'HHH','1/1/2010')
INSERT @TableA VALUES(10,111,'III','1/1/2010')

INSERT @TableB VALUES( 1,111,'AAA','1/1/2010')
INSERT @TableB VALUES( 3,333,'CCC','1/1/2010')
INSERT @TableB VALUES( 4,444,'DD' ,'1/1/2010')
INSERT @TableB VALUES( 5,555,'EEE','2/2/2010')
INSERT @TableB VALUES( 6,666,'FFF','1/1/2010')
INSERT @TableB VALUES( 7,777,'GGG','1/1/2010')
INSERT @TableB VALUES( 8,888,'ZZZ','1/1/2010')
INSERT @TableB VALUES( 9,888,'HHH','1/1/2010')
INSERT @TableB VALUES(10,111,'III','1/1/2010')
set nocount off

SELECT
    a.RowID, CASE WHEN b.RowID IS NULL THEN 'A' ELSE '' END AS RowsOnlyExistsIn
        ,a.Col1,b.Col1, CASE WHEN a.Col1=b.Col1 OR (COALESCE(a.Col1,b.Col1) IS NULL) THEN 'N' ELSE 'Y' END AS Col1Diff
        ,a.Col2,b.Col2, CASE WHEN a.Col2=b.Col2 OR (COALESCE(a.Col2,b.Col2) IS NULL) THEN 'N' ELSE 'Y' END AS Col2Diff
        ,a.Col3,b.Col3, CASE WHEN a.Col3=b.Col3 OR (COALESCE(a.Col3,b.Col3) IS NULL) THEN 'N' ELSE 'Y' END AS Col3Diff
    FROM @TableA                 a
        LEFT OUTER JOIN @TableB  b On a.RowID=b.RowID
UNION ALL
SELECT
    b.RowID, 'B' AS RowsOnlyExistsIn
        ,null,b.Col1, 'Y' AS Col1Diff
        ,null,b.Col2, 'Y' AS Col2Diff
        ,null,b.Col3, 'Y' AS Col3Diff
    FROM @TableB                 b
    WHERE b.RowID NOT IN (SELECT RowID FROM @TableA)
ORDER BY 1
输出:

RowID       RowsOnlyExistsIn Col1        Col1        Col1Diff Col2  Col2  Col2Diff Col3                    Col3                    Col3Diff
----------- ---------------- ----------- ----------- -------- ----- ----- -------- ----------------------- ----------------------- --------
1                            111         111         N        AAA   AAA   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
2           A                222         NULL        Y        BBB   NULL  Y        2010-01-01 00:00:00.000 NULL                    Y
3                            333         333         N        CCC   CCC   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
4                            444         444         N        DDD   DD    Y        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
5                            555         555         N        EEE   EEE   N        2010-01-01 00:00:00.000 2010-02-02 00:00:00.000 Y
6                            666         666         N        FFF   FFF   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
7                            777         777         N        GGG   GGG   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
8           B                NULL        888         Y        NULL  ZZZ   Y        NULL                    2010-01-01 00:00:00.000 Y
9                            888         888         N        HHH   HHH   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
10                           111         111         N        III   III   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N

(10 row(s) affected)
当然,您需要动态地生成它,以便可以比较任意两个表。此查询将获取任何表的列:

SELECT
    *
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE 
        TABLE_CATALOG   ='database'
        AND TABLE_SCHEMA='dbo'
        AND TABLE_NAME  ='yourtable'
    ORDER BY ORDINAL_POSITION
这是一个快速的动态sql版本(我尝试拉入所有PK列并使用它们动态地联接表,但我只在具有1个PK列的表上测试了它):

设置动态sql

CREATE TABLE TableA (RowID int primary key, Col1 int, Col2 varchar(5), Col3 datetime)
CREATE TABLE TableB (RowID int primary key, Col1 int, Col2 varchar(5), Col3 datetime)
set nocount on
INSERT TableA VALUES( 1,111,'AAA','1/1/2010')
INSERT TableA VALUES( 2,222,'BBB','1/1/2010')
INSERT TableA VALUES( 3,333,'CCC','1/1/2010')
INSERT TableA VALUES( 4,444,'DDD','1/1/2010')
INSERT TableA VALUES( 5,555,'EEE','1/1/2010')
INSERT TableA VALUES( 6,666,'FFF','1/1/2010')
INSERT TableA VALUES( 7,777,'GGG','1/1/2010')
INSERT TableA VALUES( 9,888,'HHH','1/1/2010')
INSERT TableA VALUES(10,111,'III','1/1/2010')

INSERT TableB VALUES( 1,111,'AAA','1/1/2010')
INSERT TableB VALUES( 3,333,'CCC','1/1/2010')
INSERT TableB VALUES( 4,444,'DD' ,'1/1/2010')
INSERT TableB VALUES( 5,555,'EEE','2/2/2010')
INSERT TableB VALUES( 6,666,'FFF','1/1/2010')
INSERT TableB VALUES( 7,777,'GGG','1/1/2010')
INSERT TableB VALUES( 8,888,'ZZZ','1/1/2010')
INSERT TableB VALUES( 9,888,'HHH','1/1/2010')
INSERT TableB VALUES(10,111,'III','1/1/2010')
set nocount off
DECLARE @TableA   sysname
       ,@TableB   sysname
       ,@SQLa     varchar(max)
       ,@SQLb     varchar(max)
       ,@SQL      varchar(max)
SELECT @TableA='TableA'
      ,@TableB='TableB'
      ,@SQLa=NULL
      ,@SQLb=NULL

DECLARE @PKs      table (RowID int identity(1,1) primary key, PkColumn sysname)
DECLARE @index_id int
       ,@PK       sysname
       ,@i        int
SELECT @index_id=index_id from sys.indexes where object_id=OBJECT_ID(@TableA) AND is_primary_key=1

SELECT @PK=''
      ,@i=0
while (@PK is not null)
BEGIN
    SET @i=@i+1
    SELECT @PK = index_col(@TableA, @index_id, @i)
    IF @PK IS NULL BREAK
    INSERT INTO @PKs (PkColumn) VALUES (@PK)
END

SELECT @SQLa=''
      ,@SQLb=''''+@TableB+''' '
SELECT
    @SQLa=@SQLa+' ,a.'+COLUMN_NAME+',b.'+COLUMN_NAME+', CASE WHEN a.'+COLUMN_NAME+'=b.'+COLUMN_NAME+' OR (COALESCE(a.'+COLUMN_NAME+',b.'+COLUMN_NAME+') IS NULL) THEN ''N'' ELSE ''Y'' END AS '+COLUMN_NAME+'Diff '
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME  =@TableA
    ORDER BY ORDINAL_POSITION

SELECT
    @SQLb=@SQLb+' ,null,b.'+COLUMN_NAME+', ''Y'' AS '+COLUMN_NAME+'Diff'
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME  =@TableA
    ORDER BY ORDINAL_POSITION

SET @SQL='SELECT CASE WHEN b.'+(SELECT PkColumn FROM @PKs WHERE RowID=1)+' IS NULL THEN '''+@TableA+''' ELSE '''' END AS RowsOnlyExistsIn '
        +@SQLa
        +'FROM '+@TableA+' a LEFT OUTER JOIN '+@TableB+' b ON '

SELECT
    @SQL=@SQL+ CASE WHEN RowID!=1 THEN 'AND ' ELSE '' END +'a.'+PkColumn+'=b.'+PkColumn+' '
    FROM @PKs

SET @SQL=@SQL+' UNION ALL SELECT '
        +@SQLb
        +' FROM '+@TableB+' b LEFT OUTER JOIN '+@TableA+' A ON '

SELECT
    @SQL=@SQL+ CASE WHEN RowID!=1 THEN 'AND ' ELSE '' END +'b.'+PkColumn+'=a.'+PkColumn+' '
    FROM @PKs

SET @SQL=@SQL+'WHERE a.'+(SELECT PkColumn FROM @PKs WHERE RowID=1)+' IS NULL ORDER BY 2,3'

EXEC(@SQL)
动态sql

CREATE TABLE TableA (RowID int primary key, Col1 int, Col2 varchar(5), Col3 datetime)
CREATE TABLE TableB (RowID int primary key, Col1 int, Col2 varchar(5), Col3 datetime)
set nocount on
INSERT TableA VALUES( 1,111,'AAA','1/1/2010')
INSERT TableA VALUES( 2,222,'BBB','1/1/2010')
INSERT TableA VALUES( 3,333,'CCC','1/1/2010')
INSERT TableA VALUES( 4,444,'DDD','1/1/2010')
INSERT TableA VALUES( 5,555,'EEE','1/1/2010')
INSERT TableA VALUES( 6,666,'FFF','1/1/2010')
INSERT TableA VALUES( 7,777,'GGG','1/1/2010')
INSERT TableA VALUES( 9,888,'HHH','1/1/2010')
INSERT TableA VALUES(10,111,'III','1/1/2010')

INSERT TableB VALUES( 1,111,'AAA','1/1/2010')
INSERT TableB VALUES( 3,333,'CCC','1/1/2010')
INSERT TableB VALUES( 4,444,'DD' ,'1/1/2010')
INSERT TableB VALUES( 5,555,'EEE','2/2/2010')
INSERT TableB VALUES( 6,666,'FFF','1/1/2010')
INSERT TableB VALUES( 7,777,'GGG','1/1/2010')
INSERT TableB VALUES( 8,888,'ZZZ','1/1/2010')
INSERT TableB VALUES( 9,888,'HHH','1/1/2010')
INSERT TableB VALUES(10,111,'III','1/1/2010')
set nocount off
DECLARE @TableA   sysname
       ,@TableB   sysname
       ,@SQLa     varchar(max)
       ,@SQLb     varchar(max)
       ,@SQL      varchar(max)
SELECT @TableA='TableA'
      ,@TableB='TableB'
      ,@SQLa=NULL
      ,@SQLb=NULL

DECLARE @PKs      table (RowID int identity(1,1) primary key, PkColumn sysname)
DECLARE @index_id int
       ,@PK       sysname
       ,@i        int
SELECT @index_id=index_id from sys.indexes where object_id=OBJECT_ID(@TableA) AND is_primary_key=1

SELECT @PK=''
      ,@i=0
while (@PK is not null)
BEGIN
    SET @i=@i+1
    SELECT @PK = index_col(@TableA, @index_id, @i)
    IF @PK IS NULL BREAK
    INSERT INTO @PKs (PkColumn) VALUES (@PK)
END

SELECT @SQLa=''
      ,@SQLb=''''+@TableB+''' '
SELECT
    @SQLa=@SQLa+' ,a.'+COLUMN_NAME+',b.'+COLUMN_NAME+', CASE WHEN a.'+COLUMN_NAME+'=b.'+COLUMN_NAME+' OR (COALESCE(a.'+COLUMN_NAME+',b.'+COLUMN_NAME+') IS NULL) THEN ''N'' ELSE ''Y'' END AS '+COLUMN_NAME+'Diff '
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME  =@TableA
    ORDER BY ORDINAL_POSITION

SELECT
    @SQLb=@SQLb+' ,null,b.'+COLUMN_NAME+', ''Y'' AS '+COLUMN_NAME+'Diff'
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME  =@TableA
    ORDER BY ORDINAL_POSITION

SET @SQL='SELECT CASE WHEN b.'+(SELECT PkColumn FROM @PKs WHERE RowID=1)+' IS NULL THEN '''+@TableA+''' ELSE '''' END AS RowsOnlyExistsIn '
        +@SQLa
        +'FROM '+@TableA+' a LEFT OUTER JOIN '+@TableB+' b ON '

SELECT
    @SQL=@SQL+ CASE WHEN RowID!=1 THEN 'AND ' ELSE '' END +'a.'+PkColumn+'=b.'+PkColumn+' '
    FROM @PKs

SET @SQL=@SQL+' UNION ALL SELECT '
        +@SQLb
        +' FROM '+@TableB+' b LEFT OUTER JOIN '+@TableA+' A ON '

SELECT
    @SQL=@SQL+ CASE WHEN RowID!=1 THEN 'AND ' ELSE '' END +'b.'+PkColumn+'=a.'+PkColumn+' '
    FROM @PKs

SET @SQL=@SQL+'WHERE a.'+(SELECT PkColumn FROM @PKs WHERE RowID=1)+' IS NULL ORDER BY 2,3'

EXEC(@SQL)
输出:

RowsOnlyExistsIn RowID       RowID       RowIDDiff Col1        Col1        Col1Diff Col2  Col2  Col2Diff Col3                    Col3                    Col3Diff
---------------- ----------- ----------- --------- ----------- ----------- -------- ----- ----- -------- ----------------------- ----------------------- --------
TableB           NULL        8           Y         NULL        888         Y        NULL  ZZZ   Y        NULL                    2010-01-01 00:00:00.000 Y
                 1           1           N         111         111         N        AAA   AAA   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
TableA           2           NULL        Y         222         NULL        Y        BBB   NULL  Y        2010-01-01 00:00:00.000 NULL                    Y
                 3           3           N         333         333         N        CCC   CCC   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
                 4           4           N         444         444         N        DDD   DD    Y        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
                 5           5           N         555         555         N        EEE   EEE   N        2010-01-01 00:00:00.000 2010-02-02 00:00:00.000 Y
                 6           6           N         666         666         N        FFF   FFF   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
                 7           7           N         777         777         N        GGG   GGG   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
                 9           9           N         888         888         N        HHH   HHH   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
                 10          10          N         111         111         N        III   III   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N

(10 row(s) affected)

由于听起来您只想在应用程序中显示差异,只需编写自己的查询,这并不难,下面是一个示例:

DECLARE @TableA table (RowID int, Col1 int, Col2 varchar(5), Col3 datetime)
DECLARE @TableB table (RowID int, Col1 int, Col2 varchar(5), Col3 datetime)
set nocount on
INSERT @TableA VALUES( 1,111,'AAA','1/1/2010')
INSERT @TableA VALUES( 2,222,'BBB','1/1/2010')
INSERT @TableA VALUES( 3,333,'CCC','1/1/2010')
INSERT @TableA VALUES( 4,444,'DDD','1/1/2010')
INSERT @TableA VALUES( 5,555,'EEE','1/1/2010')
INSERT @TableA VALUES( 6,666,'FFF','1/1/2010')
INSERT @TableA VALUES( 7,777,'GGG','1/1/2010')
INSERT @TableA VALUES( 9,888,'HHH','1/1/2010')
INSERT @TableA VALUES(10,111,'III','1/1/2010')

INSERT @TableB VALUES( 1,111,'AAA','1/1/2010')
INSERT @TableB VALUES( 3,333,'CCC','1/1/2010')
INSERT @TableB VALUES( 4,444,'DD' ,'1/1/2010')
INSERT @TableB VALUES( 5,555,'EEE','2/2/2010')
INSERT @TableB VALUES( 6,666,'FFF','1/1/2010')
INSERT @TableB VALUES( 7,777,'GGG','1/1/2010')
INSERT @TableB VALUES( 8,888,'ZZZ','1/1/2010')
INSERT @TableB VALUES( 9,888,'HHH','1/1/2010')
INSERT @TableB VALUES(10,111,'III','1/1/2010')
set nocount off

SELECT
    a.RowID, CASE WHEN b.RowID IS NULL THEN 'A' ELSE '' END AS RowsOnlyExistsIn
        ,a.Col1,b.Col1, CASE WHEN a.Col1=b.Col1 OR (COALESCE(a.Col1,b.Col1) IS NULL) THEN 'N' ELSE 'Y' END AS Col1Diff
        ,a.Col2,b.Col2, CASE WHEN a.Col2=b.Col2 OR (COALESCE(a.Col2,b.Col2) IS NULL) THEN 'N' ELSE 'Y' END AS Col2Diff
        ,a.Col3,b.Col3, CASE WHEN a.Col3=b.Col3 OR (COALESCE(a.Col3,b.Col3) IS NULL) THEN 'N' ELSE 'Y' END AS Col3Diff
    FROM @TableA                 a
        LEFT OUTER JOIN @TableB  b On a.RowID=b.RowID
UNION ALL
SELECT
    b.RowID, 'B' AS RowsOnlyExistsIn
        ,null,b.Col1, 'Y' AS Col1Diff
        ,null,b.Col2, 'Y' AS Col2Diff
        ,null,b.Col3, 'Y' AS Col3Diff
    FROM @TableB                 b
    WHERE b.RowID NOT IN (SELECT RowID FROM @TableA)
ORDER BY 1
输出:

RowID       RowsOnlyExistsIn Col1        Col1        Col1Diff Col2  Col2  Col2Diff Col3                    Col3                    Col3Diff
----------- ---------------- ----------- ----------- -------- ----- ----- -------- ----------------------- ----------------------- --------
1                            111         111         N        AAA   AAA   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
2           A                222         NULL        Y        BBB   NULL  Y        2010-01-01 00:00:00.000 NULL                    Y
3                            333         333         N        CCC   CCC   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
4                            444         444         N        DDD   DD    Y        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
5                            555         555         N        EEE   EEE   N        2010-01-01 00:00:00.000 2010-02-02 00:00:00.000 Y
6                            666         666         N        FFF   FFF   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
7                            777         777         N        GGG   GGG   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
8           B                NULL        888         Y        NULL  ZZZ   Y        NULL                    2010-01-01 00:00:00.000 Y
9                            888         888         N        HHH   HHH   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
10                           111         111         N        III   III   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N

(10 row(s) affected)
当然,您需要动态地生成它,以便可以比较任意两个表。此查询将获取任何表的列:

SELECT
    *
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE 
        TABLE_CATALOG   ='database'
        AND TABLE_SCHEMA='dbo'
        AND TABLE_NAME  ='yourtable'
    ORDER BY ORDINAL_POSITION
这是一个快速的动态sql版本(我尝试拉入所有PK列并使用它们动态地联接表,但我只在具有1个PK列的表上测试了它):

设置动态sql

CREATE TABLE TableA (RowID int primary key, Col1 int, Col2 varchar(5), Col3 datetime)
CREATE TABLE TableB (RowID int primary key, Col1 int, Col2 varchar(5), Col3 datetime)
set nocount on
INSERT TableA VALUES( 1,111,'AAA','1/1/2010')
INSERT TableA VALUES( 2,222,'BBB','1/1/2010')
INSERT TableA VALUES( 3,333,'CCC','1/1/2010')
INSERT TableA VALUES( 4,444,'DDD','1/1/2010')
INSERT TableA VALUES( 5,555,'EEE','1/1/2010')
INSERT TableA VALUES( 6,666,'FFF','1/1/2010')
INSERT TableA VALUES( 7,777,'GGG','1/1/2010')
INSERT TableA VALUES( 9,888,'HHH','1/1/2010')
INSERT TableA VALUES(10,111,'III','1/1/2010')

INSERT TableB VALUES( 1,111,'AAA','1/1/2010')
INSERT TableB VALUES( 3,333,'CCC','1/1/2010')
INSERT TableB VALUES( 4,444,'DD' ,'1/1/2010')
INSERT TableB VALUES( 5,555,'EEE','2/2/2010')
INSERT TableB VALUES( 6,666,'FFF','1/1/2010')
INSERT TableB VALUES( 7,777,'GGG','1/1/2010')
INSERT TableB VALUES( 8,888,'ZZZ','1/1/2010')
INSERT TableB VALUES( 9,888,'HHH','1/1/2010')
INSERT TableB VALUES(10,111,'III','1/1/2010')
set nocount off
DECLARE @TableA   sysname
       ,@TableB   sysname
       ,@SQLa     varchar(max)
       ,@SQLb     varchar(max)
       ,@SQL      varchar(max)
SELECT @TableA='TableA'
      ,@TableB='TableB'
      ,@SQLa=NULL
      ,@SQLb=NULL

DECLARE @PKs      table (RowID int identity(1,1) primary key, PkColumn sysname)
DECLARE @index_id int
       ,@PK       sysname
       ,@i        int
SELECT @index_id=index_id from sys.indexes where object_id=OBJECT_ID(@TableA) AND is_primary_key=1

SELECT @PK=''
      ,@i=0
while (@PK is not null)
BEGIN
    SET @i=@i+1
    SELECT @PK = index_col(@TableA, @index_id, @i)
    IF @PK IS NULL BREAK
    INSERT INTO @PKs (PkColumn) VALUES (@PK)
END

SELECT @SQLa=''
      ,@SQLb=''''+@TableB+''' '
SELECT
    @SQLa=@SQLa+' ,a.'+COLUMN_NAME+',b.'+COLUMN_NAME+', CASE WHEN a.'+COLUMN_NAME+'=b.'+COLUMN_NAME+' OR (COALESCE(a.'+COLUMN_NAME+',b.'+COLUMN_NAME+') IS NULL) THEN ''N'' ELSE ''Y'' END AS '+COLUMN_NAME+'Diff '
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME  =@TableA
    ORDER BY ORDINAL_POSITION

SELECT
    @SQLb=@SQLb+' ,null,b.'+COLUMN_NAME+', ''Y'' AS '+COLUMN_NAME+'Diff'
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME  =@TableA
    ORDER BY ORDINAL_POSITION

SET @SQL='SELECT CASE WHEN b.'+(SELECT PkColumn FROM @PKs WHERE RowID=1)+' IS NULL THEN '''+@TableA+''' ELSE '''' END AS RowsOnlyExistsIn '
        +@SQLa
        +'FROM '+@TableA+' a LEFT OUTER JOIN '+@TableB+' b ON '

SELECT
    @SQL=@SQL+ CASE WHEN RowID!=1 THEN 'AND ' ELSE '' END +'a.'+PkColumn+'=b.'+PkColumn+' '
    FROM @PKs

SET @SQL=@SQL+' UNION ALL SELECT '
        +@SQLb
        +' FROM '+@TableB+' b LEFT OUTER JOIN '+@TableA+' A ON '

SELECT
    @SQL=@SQL+ CASE WHEN RowID!=1 THEN 'AND ' ELSE '' END +'b.'+PkColumn+'=a.'+PkColumn+' '
    FROM @PKs

SET @SQL=@SQL+'WHERE a.'+(SELECT PkColumn FROM @PKs WHERE RowID=1)+' IS NULL ORDER BY 2,3'

EXEC(@SQL)
动态sql

CREATE TABLE TableA (RowID int primary key, Col1 int, Col2 varchar(5), Col3 datetime)
CREATE TABLE TableB (RowID int primary key, Col1 int, Col2 varchar(5), Col3 datetime)
set nocount on
INSERT TableA VALUES( 1,111,'AAA','1/1/2010')
INSERT TableA VALUES( 2,222,'BBB','1/1/2010')
INSERT TableA VALUES( 3,333,'CCC','1/1/2010')
INSERT TableA VALUES( 4,444,'DDD','1/1/2010')
INSERT TableA VALUES( 5,555,'EEE','1/1/2010')
INSERT TableA VALUES( 6,666,'FFF','1/1/2010')
INSERT TableA VALUES( 7,777,'GGG','1/1/2010')
INSERT TableA VALUES( 9,888,'HHH','1/1/2010')
INSERT TableA VALUES(10,111,'III','1/1/2010')

INSERT TableB VALUES( 1,111,'AAA','1/1/2010')
INSERT TableB VALUES( 3,333,'CCC','1/1/2010')
INSERT TableB VALUES( 4,444,'DD' ,'1/1/2010')
INSERT TableB VALUES( 5,555,'EEE','2/2/2010')
INSERT TableB VALUES( 6,666,'FFF','1/1/2010')
INSERT TableB VALUES( 7,777,'GGG','1/1/2010')
INSERT TableB VALUES( 8,888,'ZZZ','1/1/2010')
INSERT TableB VALUES( 9,888,'HHH','1/1/2010')
INSERT TableB VALUES(10,111,'III','1/1/2010')
set nocount off
DECLARE @TableA   sysname
       ,@TableB   sysname
       ,@SQLa     varchar(max)
       ,@SQLb     varchar(max)
       ,@SQL      varchar(max)
SELECT @TableA='TableA'
      ,@TableB='TableB'
      ,@SQLa=NULL
      ,@SQLb=NULL

DECLARE @PKs      table (RowID int identity(1,1) primary key, PkColumn sysname)
DECLARE @index_id int
       ,@PK       sysname
       ,@i        int
SELECT @index_id=index_id from sys.indexes where object_id=OBJECT_ID(@TableA) AND is_primary_key=1

SELECT @PK=''
      ,@i=0
while (@PK is not null)
BEGIN
    SET @i=@i+1
    SELECT @PK = index_col(@TableA, @index_id, @i)
    IF @PK IS NULL BREAK
    INSERT INTO @PKs (PkColumn) VALUES (@PK)
END

SELECT @SQLa=''
      ,@SQLb=''''+@TableB+''' '
SELECT
    @SQLa=@SQLa+' ,a.'+COLUMN_NAME+',b.'+COLUMN_NAME+', CASE WHEN a.'+COLUMN_NAME+'=b.'+COLUMN_NAME+' OR (COALESCE(a.'+COLUMN_NAME+',b.'+COLUMN_NAME+') IS NULL) THEN ''N'' ELSE ''Y'' END AS '+COLUMN_NAME+'Diff '
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME  =@TableA
    ORDER BY ORDINAL_POSITION

SELECT
    @SQLb=@SQLb+' ,null,b.'+COLUMN_NAME+', ''Y'' AS '+COLUMN_NAME+'Diff'
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME  =@TableA
    ORDER BY ORDINAL_POSITION

SET @SQL='SELECT CASE WHEN b.'+(SELECT PkColumn FROM @PKs WHERE RowID=1)+' IS NULL THEN '''+@TableA+''' ELSE '''' END AS RowsOnlyExistsIn '
        +@SQLa
        +'FROM '+@TableA+' a LEFT OUTER JOIN '+@TableB+' b ON '

SELECT
    @SQL=@SQL+ CASE WHEN RowID!=1 THEN 'AND ' ELSE '' END +'a.'+PkColumn+'=b.'+PkColumn+' '
    FROM @PKs

SET @SQL=@SQL+' UNION ALL SELECT '
        +@SQLb
        +' FROM '+@TableB+' b LEFT OUTER JOIN '+@TableA+' A ON '

SELECT
    @SQL=@SQL+ CASE WHEN RowID!=1 THEN 'AND ' ELSE '' END +'b.'+PkColumn+'=a.'+PkColumn+' '
    FROM @PKs

SET @SQL=@SQL+'WHERE a.'+(SELECT PkColumn FROM @PKs WHERE RowID=1)+' IS NULL ORDER BY 2,3'

EXEC(@SQL)
输出:

RowsOnlyExistsIn RowID       RowID       RowIDDiff Col1        Col1        Col1Diff Col2  Col2  Col2Diff Col3                    Col3                    Col3Diff
---------------- ----------- ----------- --------- ----------- ----------- -------- ----- ----- -------- ----------------------- ----------------------- --------
TableB           NULL        8           Y         NULL        888         Y        NULL  ZZZ   Y        NULL                    2010-01-01 00:00:00.000 Y
                 1           1           N         111         111         N        AAA   AAA   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
TableA           2           NULL        Y         222         NULL        Y        BBB   NULL  Y        2010-01-01 00:00:00.000 NULL                    Y
                 3           3           N         333         333         N        CCC   CCC   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
                 4           4           N         444         444         N        DDD   DD    Y        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
                 5           5           N         555         555         N        EEE   EEE   N        2010-01-01 00:00:00.000 2010-02-02 00:00:00.000 Y
                 6           6           N         666         666         N        FFF   FFF   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
                 7           7           N         777         777         N        GGG   GGG   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
                 9           9           N         888         888         N        HHH   HHH   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N
                 10          10          N         111         111         N        III   III   N        2010-01-01 00:00:00.000 2010-01-01 00:00:00.000 N

(10 row(s) affected)

一,;我假设您想要比较数据而不是模式,并且我假设这些表位于diff数据库中。 我不会在SQL中这样做,而是在generic.Net DataSet中加载数据,并通过表进行迭代
对象、列和行。这样,一段代码就可以用于任何数据库表,不需要笨拙的动态SQL,但是缺点是可能会影响性能,因为您需要将数据加载到数据集中-在这种情况下,只需在SQL server本身上运行代码,并将结果文件转储到文件共享中。

I;我假设您想要比较数据而不是模式,并且我假设这些表位于diff数据库中。 我不会在SQL中这样做,而是在generic.Net DataSet中加载数据,并通过表进行迭代
对象、列和行。这样,一段代码就可以用于任何数据库表,而无需使用笨拙的动态SQL,但是,缺点是可能会影响性能,因为您需要将数据加载到数据集中—在这种情况下,只需在SQl server本身上运行代码并将结果文件转储到文件共享。

开源DiffKit将完成除.NET部分之外的所有操作


www.diffkit.org

开源diffkit将完成除.NET部分之外的所有功能


www.diffkit.org

谢谢你的代码。将其假脱机到文件是xp\u cmdshell的唯一方法吗?如果您的应用程序中需要它,为什么不直接从应用程序中查询并读取查询结果呢。如果您真的需要文件,请看这里:您可以创建一个表并将数据插入其中,然后使用BCP或转换此代码来创建视图,然后使用BCP that或任何其他方法。谢谢您的代码。将其假脱机到文件是xp\u cmdshell的唯一方法吗?如果您的应用程序中需要它,为什么不直接从应用程序中查询并读取查询结果呢。如果您确实需要一个文件,请看这里:您可以创建一个表并将数据插入其中,然后使用BCP或转换此代码来创建一个视图,然后使用BCP that或任何其他方法。