0

我正在开发一个 IronPython (v2.7.3) 模块,该模块连接到远程机器上的给定 SQL Server 数据库,并使用 SMO 为该数据库的所有对象生成脚本。我的“真实”模块具有为 SMO 中定义的每个对象类型生成脚本的代码,从ApplicationRolesXmlSchemaCollections. 我正在使用的数据库是在 SQL Server 2000 上。它有相当多的对象——117 个表、257 个 SP、101 个视图等。

每次我运行我的模块时,我都会在它为 SP 编写脚本的位置获得一个堆栈跟踪。我精简到模块以仅对表和 SP 编写脚本,但在编写 SP 脚本时仍然失败。这是精简版:

import sys, clr
import System.Array

serverName     = r'x.x.x.x' #IP address of remote server
pathAssemblies = r'C:\Program Files\Microsoft SQL Server\100\Setup Bootstrap\SQLServer2008R2\x64'
sys.path.append(pathAssemblies)
clr.AddReferenceToFile('Microsoft.SqlServer.Smo.dll')
import Microsoft.SqlServer.Management.Smo as SMO

srv  = SMO.Server(serverName)
srv.ConnectionContext.LoginSecure = False
srv.ConnectionContext.Login = 'sa'
srv.ConnectionContext.Password = 'foo' #Password of sa
db = srv.Databases['bar']  #Name of database
scrp = SMO.Scripter(srv)

sys.stdout = open('DBScriptOutput.txt', 'w')

try:
    for dbgenobj in db.Tables:
       urns = System.Array[SMO.SqlSmoObject]([dbgenobj])
       outStr = scrp.Script(urns)
       for outLine in outStr:print outLine
except:
    print 'Failed out while generating table scripts.'

try:
    for dbgenobj in db.StoredProcedures:
       urns = System.Array[SMO.SqlSmoObject]([dbgenobj])
       outStr = scrp.Script(urns)
       for outLine in outStr:print outLine
except:
    print 'Failed out while generating stored procedure scripts.'

这里让我难过的谜题涉及两件似乎没有意义的事情:

(1) 堆栈轨道本身如下所示:

Traceback (most recent call last):
  File "E:\t.py", line 33, in <module>
UnicodeEncodeError: ('unknown', '\x00', 0, 1, '')

第 33 行是块中的print语句except。输出文件包含所有表的脚本、235 个 SP 的完整脚本和第 236 个的部分脚本。但是关于#236 并没有什么不寻常的(我无论如何都可以看到)会导致脚本失败。print我也无法理解为什么引用块中的简单语句会发生堆栈跟踪except

(2) 作为进一步的故障排除实验,我尝试在try-except注释掉表的整个块的情况下运行脚本。它仍然无法生成 SP 脚本,并生成引用第 33 行的相同堆栈跟踪。不同之处在于,这次它在终止之前成功地为过程 #236 生成了另外 16 行脚本。但是,输出文件的整体文件大小要小得多。我可以理解文件是否以相同的大小停止,或者脚本是否停止在 SP 中的同一点,但这些都不是真的。

因此,在这一点上,(显然)排除了 SP 中的问题字符或脚本过程的文件/内存大小限制,我很难过。

4

1 回答 1

1

我在注释中有非 ASCII 字符的过程中遇到了这个问题。最简单的解决方案是使用编解码器模块而codecs.open不是普通open调用。将此添加到导入行:

import codecs

然后将open调用替换为:

sys.stdout = codecs.open('DBScriptOutput.txt', 'w', 'utf8')

这对我有用。

于 2013-09-17T12:23:28.027 回答