@echo off
if not exist tables.txt (goto end)
:sourceserver
set sourceserver=
set /p sourceserver=请输入源机器名字
if "%sourceserver%" == "" goto sourceserver
:sourcedatabase
set sourcedatabase=
set /p sourcedatabase=请输入源数据库名字
if "%sourcedatabase%" == "" goto sourcedatabase
:sourceschema
set sourceschema=
set /p sourceschema=请输入源架构名
if "%sourceschema%" == "" goto sourceschema
:sourceuser
set sourceuser=
set /p sourceuser=请输入源用户名
if "%sourceuser%" == "" goto sourceuser
:sourcepassword
set sourcepassword=
set /p sourcepassword=请输入源用户密码
if "%sourcepassword%" == "" goto sourcepassword
:destinationserver
set destinationserver=
set /p destinationserver=请输入目的机器名字
if "%destinationserver%" == "" goto destinationserver
:destinationdatabase
set destinationdatabase=
set /p destinationdatabase=请输入目的数据库名字
if "%destinationdatabase%" == "" goto destinationdatabase
:destinationschema
set destinationschema=
set /p destinationschema=请输入目的架构名
if "%destinationschema%" == "" goto destinationschema
:destinationuser
set destinationuser=
set /p destinationuser=请输入目的用户名
if "%destinationuser%" == "" goto destinationuser
:destinationpassword
set destinationpassword=
set /p destinationpassword=请输入目的用户密码
if "%destinationpassword%" == "" goto destinationpassword
:datapath
set datapath=
set /p datapath=请输入保存生成文件的路径(默认为当前目录):
for /F %%i in (tables.txt) do @echo tablediff /sourceserver"%sourceserver%" /sourcedatabase"%sourcedatabase%" /sourceschema"%sourceschema%" /sourcetable"%%i" /sourceuser"%sourceuser%" /sourcepassword"%sourcepassword%" /destinationserver"%destinationserver%" /destinationdatabase"%destinationdatabase%" /destinationschema"%destinationschema%" /destinationtable"%%i" /destinationuser"%destinationuser%" /destinationpassword"%destinationpassword%" /f"%datapath%.\syn%%i-%destinationserver%.sql" /o"%datapath%.\output-%%i-%destinationserver%.txt">>tabcompc.bat
rem echo copy syn*%destinationserver%.sql syn%destinationserver%-Z.SQL>>tabcomp.bat
rem echo sqlcmd -S%destinationserver% -U%destinationuser% -P%destinationpassword% -d %destinationdatabase% -f i:65001 -i syn%destinationserver%-Z.SQL -o execsyn%destinationserver%.log>>tabcomp.bat
echo for %%%%f in (*.sql) do sqlcmd -S %destinationserver% -U %destinationuser% -P %destinationpassword% -d %destinationdatabase% -f i:65001 -i %%%%f -o execsyn%%%%f.log>>tabcompc.bat
set sourceserver=
set sourcedatabase=
set sourceschema=
set sourcetable=
set sourcelocked=
set sourceuser=
set sourcepassword=
set destinationdatabase=
set destinationlocked=
set destinationpassword=
set destinationschema=
set destinationserver=
set destinationtable=
set destinationuser=
set datapath=
:end
echo tables.txt文件不存在请手工生成该文件
以上的批处理中有两行注释掉了,这两行的功能是分别将TABLEDIFF生成的SQL文件使用SQLCMD命令行到目的机器上去执行,只使用一行就行,这两行的差异在于将生成的多个SQL文件是分别执行还是合并在一起执行,如果合并在一起执行的话,SQL文件就会很大,但SQLCMD这个工具对大的SQL文件执行会报“内存不足”的错误,咨询过微软也没有好的解决方案,只能算是这个EXE的特点了。
但如果是在SQL2000的环境通过TABLEDIFF进行比差异,需要有Frame work的支持,而且SQL2000中没有SQLCMD功能,原来的ISQL和OSQL也不支持代码页的转换不向SQLCMD中有-f参数,这样对于我们做批处理就是一个小障碍。所以对于纯SQL2000的环境中要使用TABLEDIFF进行差异比对和差异数据的执行,必须要通过写字板手工转换差异SQL文件,如果要写批处理,则必须找一个命令行的UTF-8转换为UNICODE代码的工具,在网上找了一个强人写的一个VBS,试过后很爽。所以在此推荐给大家,代码如下:
' *==============================================================================*
' * CMD 命令行编码转换工具包括GB2312,UTF-8,Unicode,BIG5...支持拖拽、文件另保存为 *
' * CodeChange.vbs BY: yongfa365
' * GB2Ue.vbs BY: fastslz
' *==============================================================================*
aCode = "GB2312"
bCode = "Unicode"
Show = "本脚本仅支持"&aCode&"到"&bCode&"的转换,请拖拽单个要转换的文件到此文件上! "
Usage1 = "语法1:GB2Ue.vbs [驱动器][目录][文件名] (直接替换原文件模式)"
Usage2 = "语法2:GB2Ue.vbs [驱动器][目录][文件名] [目标驱动器][目录][新名称] /Y"
Usage3 = " 如果目标新文件已存在,使用/Y参数后将直接替换而不提示是否改写! "
Usage4 = "命令行编码转换工具 BY: fastslz"
Set objArgs=WScript.Arguments
Set fso=CreateObject("Scripting.FileSystemObject")
if objArgs.Count=0 Then
MsgBox Show &vbCrLf&vbCrLf& Usage1 &vbCrLf& Usage2 &vbCrLf& Usage3, vbInformation, Usage4
Wscript.Quit
end if
if not objArgs.Count < 3 Then
Options="/y"
ignoring = StrComp(objArgs(2), Options, vbTextCompare)
if ignoring = 0 Then
Sourcefile=objArgs(0)
Getfile=objArgs(1)
else
MsgBox "文件数量或参数太多,拖拽批量处理请用 ANSI2Unicode.vbs ", vbInformation, "程序意外终止"
Wscript.Quit
end if
else
if not objArgs.Count < 2 Then
Sourcefile=objArgs(0)
Getfile=objArgs(1)
if fso.FileExists(objArgs(1)) then
Choice = MsgBox ("待处理文件“"+Sourcefile+"” ==> 目标文件“"+Getfile+"” "&vbCrLf&"目标文件已存在,是否改写现有文件?“"+objArgs(1)+"” ",vbQuestion+vbYesNo,"是否改写")
if Choice = vbYes Then
Getfile=objArgs(1)
else
Wscript.Quit
end if
end if
else
Sourcefile=objArgs(0)
Getfile=objArgs(0)
end if
end if
Call CheckCode (Sourcefile)
Call WriteToFile(Getfile, ReadFile(Sourcefile, aCode), bCode)
Wscript.Quit
Function ReadFile (Sourcefile, CharSet)
Dim Str
Set stm = CreateObject("Adodb.Stream")
stm.Type = 2
stm.mode = 3
stm.charset = CharSet
stm.Open
stm.loadfromfile Sourcefile
Str = stm.readtext
stm.Close
Set stm = Nothing
ReadFile = Str
End Function
Function WriteToFile (Getfile, Str, CharSet)
Set stm = CreateObject("Adodb.Stream")
stm.Type = 2
stm.mode = 3
stm.charset = CharSet
stm.Open
stm.WriteText Str
stm.SaveToFile Getfile,2
stm.flush
stm.Close
Set stm = Nothing
End Function
Function CheckCode (Sourcefile)
Dim slz
set slz = CreateObject("Adodb.Stream")
slz.Type = 1
slz.Mode = 3
slz.Open
slz.Position = 0
slz.Loadfromfile Sourcefile
Bin=slz.read(2)
if AscB(MidB(Bin,1,1))=&HEF and AscB(MidB(Bin,2,1))=&HBB Then
Codes="UTF-8"
elseif AscB(MidB(Bin,1,1))=&HFF and AscB(MidB(Bin,2,1))=&HFE Then
Codes="Unicode"
else
Codes="GB2312"
end if
if not aCode = Codes Then
MsgBox "待处理文件 “"&Sourcefile&"”"&vbCrLf&"该文件原始编码不是"&aCode&",本脚本仅支持"&aCode&"到"&bCode&"的转换! ",vbInformation,"错误终止"
WScript.Quit
end if
slz.Close
set slz = Nothing
End Function
需要注意的是:
1.通过TABLEDIFF生成的差异SQL文件是UTF-8格式的,但这种格式还不完全是标准的UTF-8,我经过分析发现这种格式是UTF-8的文件头,而内容却是GB2313的,如果通过以上脚本来直接换会发现脚本报错,说此文件不是UTF-8的文件,所以,要强制转换,还需要把以上代码中的
if not aCode = Codes Then
MsgBox "待处理文件 “"&Sourcefile&"”"&vbCrLf&"该文件原始编码不是"&aCode&",本脚本仅支持"&aCode&"到"&bCode&"的转换! ",vbInformation,"错误终止"
WScript.Quit
end if
给注释掉,让他不检测文件版本,直接给按UTF-8给转换掉,这样才能通过OSQL等2000下的工具正确的执行。
2.如果把这种通过TABLEDIFF生成的差异SQL文件通过SQLCMD来执行就会出现很多码,幸好SQLCMD中有一个参数-f 通过-f i:65001这个参数就可以解决UTF-8差异数据文件执行的问题。
3.还有一点,就是SQL2005中的TABLEDIFF和SQL2008中的TABLEDIFF有差别,使用SQL2008版的TABLEDIFF不但性能差,而且生成的差异文件执行会报错,我发现的问题是对于NULL值,SQL2008版本中生成的脚本是N‘NULL’,而SQL2005中的TABLEDIFF中则生成的是NULL,所以推荐大家使用SQL2005中的TABLEDIFF文件。至于SQL2008中的TABLEDIFF会不会比SQL2005中的功能多,这点偶还没有发现,希望会有进步,但至少目前是发现了其不足。
4.最近验证了sqlserver2008r2中的tablediff工具,和sqlserver2008一样有问题,所以不得不使用sql2005中带的tablediff.exe