将XML直接从SQL Server输出到文件

时间:2019-05-24 13:45:34

标签: sql-server xml powershell

将存储过程的结果(XML)输出到文件。

我在SQL Server中有一个创建XML文件的存储过程。当前,它会显示生成的XML,我必须手动将其另存为文件。

我尝试从Powershell as in this question调用该过程,该过程适用于小型文件,但不适用于大型文件(> 1gb文件),因为Powershell尝试将整个内容存储为变量,并且很快用完了记忆。

我将其作为一个新问题开放,因为我认为应该在SQL Server中提供一种方法(或者使用Powershell更好的方法)。

2 个答案:

答案 0 :(得分:3)

您不应在此处使用存储过程。只需使用更好的PowerShell。您可以stream large types to and from SQL Server with SqlClient。因此,您只需要下拉列表并使用ADO.NET,而不是使用invoke-sqlcmd便捷方法。

EG:

$conString = "server=localhost;database=tempdb;integrated security=true"

$sql = @"

select top (1000*1000) * 
from sys.messages m
cross join sys.objects o
for xml auto

"@

$fn = "c:\temp\out.xml"

$con = new-object System.Data.SqlClient.SqlConnection
$con.connectionstring = $conString
$con.Open()

$cmd = $con.createcommand()
$cmd.CommandText = $sql 
$cmd.CommandTimeout = 0

$rdr = $cmd.ExecuteXmlReader()
$w = new-object System.Xml.XmlTextWriter($fn,[System.Text.Encoding]::UTF8)
$w.WriteNode($rdr,$true)
$w.Close()
$rdr.Close()

write-host "Process Memory: $( [System.GC]::GetTotalMemory($false) )"
write-host "File Size: $( (ls $fn)[0].Length )"

输出

Process Memory: 34738200
File Size: 468194885

答案 1 :(得分:0)

其他解决方案,如果需要的话,您必须逐行在临时表中构建XML文件,然后从Powershell或其他代码逐行输出并读取结果:

SQL示例:

/*
**
**  Stored procedure  
**
*/

/*** Effacement: ********************************************************
IF EXISTS ( SELECT name FROM sysobjects
            WHERE type = 'P' AND name = 'procTEST' )
    DROP PROCEDURE procTEST
*** Effacement: ********************************************************/

CREATE PROCEDURE procTEST
AS

CREATE TABLE #TEMP (vInfo VARCHAR(MAX), nLine int)

INSERT INTO #TEMP
SELECT 'Line 1',1
UNION ALL 
SELECT 'Line 2',2
UNION ALL 
SELECT 'Line 3',3

SELECT vInfo FROM #TEMP ORDER BY nLine ASC

SET NOCOUNT OFF

/*** TESTS ****************************************************************************************************************************************
sp_helptext procTEST

--  DROP PROCEDURE procTEST
EXEC procTEST

*** TESTS ****************************************************************************************************************************************/

Powershell脚本:

$readconn = New-Object System.Data.OleDb.OleDbConnection
$writeconn = New-Object System.Data.OleDb.OleDbConnection
[string]$connstr="Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=TEST;Data Source=.\XXXXX;Workstation ID=OMEGA2"
$readconn.connectionstring = $connstr
$readconn.open()
$readcmd = New-Object system.Data.OleDb.OleDbCommand
$readcmd.connection=$readconn
$readcmd.commandtext='EXEC procTEST'
$reader = $readcmd.executereader()
# generate header
$hash=@{}
for ($i=0;$i -lt $reader.FieldCount;$i++){
       $hash+=@{$reader.getname($i)=''}
}
$dbrecords=while($reader.read()) {
     for ($i=0;$i -lt $reader.FieldCount;$i++){
          $hash[$reader.getname($i)] = $reader.GetValue($i)

     }
   New-Object PSObject -Property $hash
}
$reader.close()
$readconn.close()
$dbrecords