O
OopsWare
Unregistered / Unconfirmed
GUEST, unregistred user!
SQL Server 2000 可以使用 FOR XML AUTO 子句将查询完整的导出到 XML 文本,
配合 ADODB.Stream 可以将XML存储成为本地文件,另外通过 SQLXML3 的 Bulk Load
可以快速的将XML恢复回数据库。 我想用这两个方法实现数据库的备份和恢复,但问题
来了:
ADODB.Stream 是一个内存流,如果查询得到了一个巨大的表,例如DFW.letters表
有几百兆,ADODB.Stream将耗尽系统内存资源而出错。有没有一种文件流的形式,
令导出和写盘同步进行???
下面是一段PB的代码,我还尚未在Delphi下测试,大家将就一下了
function f_query_to_xml(string in_query, in_table, in_where, out_filename): integer
OLEObject cmd, conn, strmOut, rset
long i, xsdfile
string fname, fldsname = ""
// 初始化 ADO Object
cmd = Create OLEObject
cmd.ConnectToNewObject("ADODB.Command")
conn = Create OLEObject
conn.ConnectToNewObject("ADODB.Connection")
strmOut = Create OLEObject
strmOut.ConnectToNewObject("ADODB.Stream")
rset = Create OLEObject
rset.ConnectToNewObject("ADODB.RecordSet")
// 连接数据库
conn.Provider = "SQLOLEDB"
conn.Open("server="+sqlca.ServerName+";database="+sqlca.Database+";uid="+sqlca.LogId+";pwd="+sqlca.LogPass)
// 创建 XSD 文件
xsdfile = FileOpen(out_filename+".xsd", LineMode!, Write!, LockWrite!, Replace!)
FileWrite(xsdfile, '<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sql="urn:schemas-microsoft-com:mapping-schema">')
FileWrite(xsdfile, '<xsd:element name="'+in_table+'" sql:relation="'+in_table+'" ><xsd:complexType><xsd:sequence>')
rset.Open("SELECT "+in_query+" FROM "+in_table+" WHERE 1=0", conn, 0, 1)
for i=0 to rset.Fields.Count()-1
fname = string( rset.Fields.Name )
if fldsname<>"" then
fldsname = fldsname + ","
choose case rset.Fields.Type
case 133, 134, 135
fldsname = fldsname + "CONVERT(varchar(10), "+fname+", 21) "+fname
FileWrite(xsdfile, '<xsd:element name="'+fname+'" sql:field="'+fname+'" type="xsd:date"/>')
case else
fldsname = fldsname + fname
FileWrite(xsdfile, '<xsd:element name="'+fname+'" sql:field="'+fname+'" type="xsd:string"/>')
end choose
next
FileWrite(xsdfile, '</xsd:sequence></xsd:complexType></xsd:element></xsd:schema>')
rset.Close()
FileClose(xsdfile)
// 生成 XML 数据
cmd.ActiveConnection = conn
cmd.Dialect = "{5d531cb2-e6ed-11d2-b252-00c04f681b71}"
cmd.CommandText = "<ROOT xmlns:sql='urn:schemas-microsoft-com:xml-sql'><sql:query>" &
+ "SELECT "+fldsname+" FROM "+in_table+" FOR XML AUTO, ELEMENTS" &
+ "</sql:query></ROOT>"
// 存为 XML 文件
strmOut.Open()
cmd.Properties("Output Stream").Value = strmOut
cmd.Execute(0, 0, 1024)
strmOut.Position = 0
strmOut.SaveToFile(out_filename+".xml", 2)
strmOut.Close()
// 释放
rset.DisConnectObject()
Destroy rset
strmOut.DisConnectObject()
Destroy strmOut
conn.DisConnectObject()
Destroy conn
cmd.DisConnectObject()
Destroy cmd
return 0
配合 ADODB.Stream 可以将XML存储成为本地文件,另外通过 SQLXML3 的 Bulk Load
可以快速的将XML恢复回数据库。 我想用这两个方法实现数据库的备份和恢复,但问题
来了:
ADODB.Stream 是一个内存流,如果查询得到了一个巨大的表,例如DFW.letters表
有几百兆,ADODB.Stream将耗尽系统内存资源而出错。有没有一种文件流的形式,
令导出和写盘同步进行???
下面是一段PB的代码,我还尚未在Delphi下测试,大家将就一下了
function f_query_to_xml(string in_query, in_table, in_where, out_filename): integer
OLEObject cmd, conn, strmOut, rset
long i, xsdfile
string fname, fldsname = ""
// 初始化 ADO Object
cmd = Create OLEObject
cmd.ConnectToNewObject("ADODB.Command")
conn = Create OLEObject
conn.ConnectToNewObject("ADODB.Connection")
strmOut = Create OLEObject
strmOut.ConnectToNewObject("ADODB.Stream")
rset = Create OLEObject
rset.ConnectToNewObject("ADODB.RecordSet")
// 连接数据库
conn.Provider = "SQLOLEDB"
conn.Open("server="+sqlca.ServerName+";database="+sqlca.Database+";uid="+sqlca.LogId+";pwd="+sqlca.LogPass)
// 创建 XSD 文件
xsdfile = FileOpen(out_filename+".xsd", LineMode!, Write!, LockWrite!, Replace!)
FileWrite(xsdfile, '<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sql="urn:schemas-microsoft-com:mapping-schema">')
FileWrite(xsdfile, '<xsd:element name="'+in_table+'" sql:relation="'+in_table+'" ><xsd:complexType><xsd:sequence>')
rset.Open("SELECT "+in_query+" FROM "+in_table+" WHERE 1=0", conn, 0, 1)
for i=0 to rset.Fields.Count()-1
fname = string( rset.Fields.Name )
if fldsname<>"" then
fldsname = fldsname + ","
choose case rset.Fields.Type
case 133, 134, 135
fldsname = fldsname + "CONVERT(varchar(10), "+fname+", 21) "+fname
FileWrite(xsdfile, '<xsd:element name="'+fname+'" sql:field="'+fname+'" type="xsd:date"/>')
case else
fldsname = fldsname + fname
FileWrite(xsdfile, '<xsd:element name="'+fname+'" sql:field="'+fname+'" type="xsd:string"/>')
end choose
next
FileWrite(xsdfile, '</xsd:sequence></xsd:complexType></xsd:element></xsd:schema>')
rset.Close()
FileClose(xsdfile)
// 生成 XML 数据
cmd.ActiveConnection = conn
cmd.Dialect = "{5d531cb2-e6ed-11d2-b252-00c04f681b71}"
cmd.CommandText = "<ROOT xmlns:sql='urn:schemas-microsoft-com:xml-sql'><sql:query>" &
+ "SELECT "+fldsname+" FROM "+in_table+" FOR XML AUTO, ELEMENTS" &
+ "</sql:query></ROOT>"
// 存为 XML 文件
strmOut.Open()
cmd.Properties("Output Stream").Value = strmOut
cmd.Execute(0, 0, 1024)
strmOut.Position = 0
strmOut.SaveToFile(out_filename+".xml", 2)
strmOut.Close()
// 释放
rset.DisConnectObject()
Destroy rset
strmOut.DisConnectObject()
Destroy strmOut
conn.DisConnectObject()
Destroy conn
cmd.DisConnectObject()
Destroy cmd
return 0