1

我目前正在尝试编写一个工具,使非计算机知识的用户可以很容易地备份 SQL Server 数据库。

为此,我希望使用 ADO、win32com 和 adodbapi 的有趣组合。目前,我可以轻松连接到服务器并发出BACKUP DATABASET-SQL 命令。

这可行,但是执行命令通常需要很长时间(尤其是在非常大的数据库上)。为此,我希望捕获和解析InfoMessage事件 ( MSDN ) 并使用它来显示百分比条/计数器。

这我也成功了,我现在陷入了最后的障碍,解析事件。MSDN文档说我应该在参数中传递一个错误错误对象pError。但是 win32com 传递给我一个PyIUnknown我不知道如何处理的对象。

以下是我到目前为止编写的代码:

import win32com
import pythoncom
import adodbapi
from win32com.client import gencache
gencache.EnsureModule('{2A75196C-D9EB-4129-B803-931327F72D5C}', 0, 2, 8)

defaultNamedOptArg=pythoncom.Empty
defaultNamedNotOptArg=pythoncom.Empty
defaultUnnamedArg=pythoncom.Empty

class events():
    def OnInfoMessage(self, pError, adStatus, pConnection):
        print 'A', pError
        #print 'B', adStatus
        #print 'C', pConnection

# This is taken from the makepy file
#    def OnCommitTransComplete(self, pError=defaultNamedNotOptArg, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): pass
    def OnWillExecute(self, Source=defaultNamedNotOptArg, CursorType=defaultNamedNotOptArg, LockType=defaultNamedNotOptArg, Options=defaultNamedNotOptArg
            , adStatus=defaultNamedNotOptArg, pCommand=defaultNamedNotOptArg, pRecordset=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg):
        return Source
#    def OnDisconnect(self, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): pass
    def OnExecuteComplete(self, RecordsAffected=defaultNamedNotOptArg, pError=defaultNamedNotOptArg, adStatus=defaultNamedNotOptArg, pCommand=defaultNamedNotOptArg
            , pRecordset=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): pass
        #print pError
    def OnWillConnect(self, ConnectionString=defaultNamedNotOptArg, UserID=defaultNamedNotOptArg, Password=defaultNamedNotOptArg, Options=defaultNamedNotOptArg
            , adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): pass
#    def OnConnectComplete(self, pError=defaultNamedNotOptArg, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): pass
#    def OnBeginTransComplete(self, TransactionLevel=defaultNamedNotOptArg, pError=defaultNamedNotOptArg, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg):pass
#    def OnRollbackTransComplete(self, pError=defaultNamedNotOptArg, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): pass




if __name__ == '__main__':

    pythoncom.CoInitialize()
    conn = win32com.client.DispatchWithEvents("ADODB.Connection", events)
    print dir(conn)
    conn.ConnectionString = 'Initial Catalog=test; Data Source=HPDX2250RAAZ\\SQLEXPRESS; Provider=SQLOLEDB.1; Integrated Security=SSPI'
    conn.CommandTimeout = 30
    print conn.ConnectionString
    conn.Open()

    con = adodbapi.Connection(conn)

    c = con.cursor()
    import time
    print 'Execute'
    time.sleep(1)
    c.execute(u"BACKUP DATABASE [test] TO DISK = N'c:/test/test2' WITH STATS = 1")
    print 'Done Execute'

任何人都可以从事件中提取信息性消息吗?

这是在VB中实现的(我认为)

对于这些消息之一的示例,启动 SQL Server Management Studio 并使用脚本运行备份(您可以使用备份对话框和左上角的脚本按钮生成脚本)。您会注意到,当您运行脚本时,消息框将填充完成百分比的消息。这些就是我想要的。

编辑:

下面是我用来询问传递给InfoMessage. 这是基于下面的答案,我把它放在这里以防其他人需要它。

def OnInfoMessage(self, pError, adStatus, pConnection):
    print 'Info Message'
    a = pError.QueryInterface(pythoncom.IID_IDispatch)
    a = win32com.client.Dispatch(a)
    print a.Description
    print a.Number
    print a.Source
    #print 'B', adStatus
    c = pConnection.QueryInterface(pythoncom.IID_IDispatch)
    c = win32com.client.Dispatch(c)
    print c.Errors.Count
    print c.Errors.Item(0).Description
    print c.Errors.Clear()
    print 'c', adStatus
4

1 回答 1

0

阅读 MSDN,似乎只有Error对象应该传递给事件处理程序。如果有多个错误,您可以从对象Errors的集合Connection获取它们。所以你应该只期望 Error 对象被传递给InfoMessage(). 如果你得到 PyIUnknown,也许你可以尝试调用QueryInterface()它并请求 IDispatch?您也可以尝试请求特定的自定义接口Error使用,但我不记得 Pythoncom 是否支持自定义(即非 IDispatch)接口,而且我的互联网现在正在爬网,所以我无法检查所以你必须检查那你自己。无论如何,IDispatch 无论如何都应该工作,因为这是 VB6 使用的。

于 2011-05-03T21:17:20.613 回答