我正在尝试使用powershell脚本导出sql文件流数据,并且它只导出高达8kb,如果文件超过8kb则无法导出。但它会部分创建文件。我不知道遗失了什么。
$Server = "(local)"; # SQL Server Instance.
$Database = "AdventureWorks";
$Dest = "D:\Export\"; # Path to export to.
$bufferSize = 8192; # Stream buffer size in bytes.
$con = New-Object Data.SqlClient.SqlConnection;
$con.ConnectionString = "Data Source=$Server;" +
"Integrated Security=True;" +
"Initial Catalog=$Database";
$con.Open();
[System.Data.SqlClient.SqlTransaction]$tran = $con.BeginTransaction("fs");
$Sql = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()";
$ctx = [array]::CreateInstance('Byte', 16);
$cmdct = New-Object Data.SqlClient.SqlCommand($Sql, $con, $tran);
$ctx = $cmdct.ExecuteScalar();
$cmdct.Dispose();
$Sql = "SELECT [FileName]
,[FileStreamData].PathName()
FROM dbo.FileStreamStorage ";
$out = [array]::CreateInstance('Byte', $bufferSize);
$cmd = New-Object Data.SqlClient.SqlCommand($Sql, $con, $tran);
$rd = $cmd.ExecuteReader();
While ($rd.Read())
{
Write-Output ("Exporting: {0}" -f $rd.GetString(0));
$fs = New-Object System.IO.FileStream ($Dest + $rd.GetString(0)), Create, Write;
$bw = New-Object System.IO.BinaryWriter($fs);
$sfs = New-Object System.Data.SqlTypes.SqlFileStream $rd.GetString(1), $ctx, Read, None, 0;
$start = 0;
While (1 -eq 1)
{
$received = $sfs.Read($out, $start, $bufferSize - 1);
$bw.Write($out, 0, $received);
$bw.Flush();
$start += $received;
If ($received -lt $bufferSize)
{ break; }
}
$bw.Close();
$fs.Close();
$sfs.Close();
}
$fs.Dispose();
$sfs.Dispose();
$rd.Close();
$rd.Dispose();
$tran.Commit();
$cmd.Dispose();
$tran.Dispose();
$con.Close();
$con.Dispose();
Write-Output ("Finished");
任何帮助都将非常感激。
答案 0 :(得分:0)
我认为你正在读取8191个字节,这意味着如果有更多的数据,那么$ received将是8191。
$received = $sfs.Read($out, $start, **$bufferSize - 1**);
然后将$ received(8191)与$ bufferSize(8192)进行比较
If ($received -lt $bufferSize)
答案 1 :(得分:0)
我已经完成了一些文件流和Powershell的工作,我同意其他评论 - 看来你的长度是多少。以下是我的博客http://sev17.com/2010/05/11/t-sql-tuesday-006-blobs-filestream-and-powershell/中的一些代码,它们演示了如何将文件流数据检索到图像文件中:
$server = "Z002sql2k8"
$database = "AdventureWorks2008"
$query = "SELECT TOP(10) Document.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT(), Title + FileExtension AS FileName FROM Production.Document WHERE FileExtension = '.doc'"
$dirPath = "C:Usersu00"
$connection=new-object System.Data.SqlClient.SQLConnection
$connection.ConnectionString="Server={0};Database={1};Integrated Security=True" -f $server,$database
$connection.Open()
$command=new-object system.Data.SqlClient.SqlCommand("",$connection)
$command.CommandTimeout=120
$tran = $connection.BeginTransaction([System.Data.IsolationLevel]'ReadCommitted')
$command.Transaction = $tran
$command.CommandText = $query
$reader = $command.ExecuteReader()
while ($reader.Read())
{
$path = $reader.GetString(0)
[byte[]]$transactionContext = $reader.GetSqlBytes(1).Buffer
$filepath = "$dirPath{0}" -f $reader.GetValue(2)
$fileStream = new-object System.Data.SqlTypes.SqlFileStream($path,[byte[]]$reader.GetValue(1), [System.IO.FileAccess]'Read', [System.IO.FileOptions]'SequentialScan', 0)
$buffer = new-object byte[] $fileStream.Length
$fileStream.Read($buffer,0,$fileStream.Length)
$fileStream.Close()
[System.IO.File]::WriteAllBytes($filepath,$buffer)
}
$reader.Close()
$tran.Commit()
$connection.Close()