Вывести XML напрямую в файл с сервера SQL - PullRequest
1 голос
/ 24 мая 2019

Вывод результатов (XML) хранимой процедуры в файл.

У меня есть хранимая процедура на сервере SQL, которая создает файл XML. В настоящее время он отображает полученный XML, и мне нужно вручную сохранить его в виде файла.

Я пытался вызвать процедуру из Powershell, , как в этом вопросе , это работает для небольших файлов, но не для больших (> 1 ГБ файлов), так как Powershell пытается сохранить всю вещь как переменную и у него быстро заканчивается память.

Я открываю это как новый вопрос, так как считаю, что должен быть способ сделать это на сервере SQL (или лучший способ сделать это с помощью Powershell).

Ответы [ 2 ]

3 голосов
/ 24 мая 2019

Вы не должны использовать хранимую процедуру здесь.Просто используйте лучше PowerShell.С помощью SqlClient вы можете транслировать большие типы в SQL Server и обратно.Так что вам просто нужно выпасть и использовать 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 )"

output

Process Memory: 34738200
File Size: 468194885
0 голосов
/ 24 мая 2019

Другое решение, если вы можете, вам нужно построить файл 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...