尝试使用 PS 脚本从 SQL 中提取数据
Posted
技术标签:
【中文标题】尝试使用 PS 脚本从 SQL 中提取数据【英文标题】:Trying to extract data form SQL using PS script 【发布时间】:2022-01-09 22:11:28 【问题描述】:我一直在尝试使用 PS 脚本从 SQL Server 数据库中提取文件(pdf、word 等)。我遇到了下面的 PowerShell 脚本。脚本运行并填充目标文件夹,但所有文件都是 0 字节并且在脚本执行期间。它抛出错误:
"从 FILESTREAM 容器中导出对象:.docx 使用“5”参数调用“GetBytes”的异常:“对列“扩展”的 GetBytes 尝试无效。GetBytes 函数只能用于 typ 列 e 文本、NText 或图像。""
谁能指出我做错了什么以及如何解决这个问题?非常感谢。
$Server = ".\xxxxxx";
$Database = "xxxxxx";
$Dest = "C:\DATA\";
$bufferSize = 8192;
$Sql = "
SELECT
[extension]
FROM [XXXXXXXX].[dbo].[XXXXXXdocuments]
";
$con = New-Object Data.SqlClient.SqlConnection;
$con.ConnectionString = "Data Source=$Server;" +
"Integrated Security=True;" +
"Initial Catalog=$Database";
$con.Open();
Write-Output ((Get-Date -format yyyy-MM-dd-HH:mm:ss) + ": Started ...");
$cmd = New-Object Data.SqlClient.SqlCommand $Sql, $con;
$cmd.CommandTimeout = 120
$rd = $cmd.ExecuteReader();
$out = [array]::CreateInstance('Byte', $bufferSize)
While ($rd.Read())
try
Write-Output ("Exporting Objects from FILESTREAM container: 0" -f $rd.GetString(0));
$fs = New-Object System.IO.FileStream ($Dest + $rd.GetString(0)), Create, Write;
$bw = New-Object System.IO.BinaryWriter $fs;
$start = 0;
enter code here
$received = $rd.Getbytes(0, $start, $out, 0, $bufferSize - 1);
While ($received -gt 0)
$bw.Write($out, 0, $received);
$bw.Flush();
$start += $received;
$received = $rd.Getbytes(0, $start, $out, 0, $bufferSize - 1);
$bw.Close();
$fs.Close();
catch
Write-Output ($_.Exception.Message)
finally
$fs.Dispose();
$rd.Close();
$cmd.Dispose();
$con.Close();
Write-Output ("Finished");
Read-Host -Prompt "Press Enter to exit"
【问题讨论】:
关于无法在GetBytes()
中调用您尝试读取的字段的数据问题,错误似乎很明显。 extension
字段的数据类型是什么?请记住varchar
或nvarchar
与text
或ntext
不同。你是把PDF、DOCX等的二进制数据保存在数据库里吗?
感谢您抽出宝贵时间查看此内容,我设法弄清楚问题是我调用的列不包含我试图提取的数据,一旦审查并纠正所有工作正常。非常感谢
【参考方案1】:
BinaryWriter 是不必要的。它用于将原始类型写入 Stream。
而且没有必要乱用缓冲区;你可以简单地使用SqlDataReader.GetStream(int).CopyTo(Stream)
,例如
$Server = "localhost";
$Database = "adventureworks2017";
$Dest = "C:\temp\";
$Sql = "
SELECT concat('photo', ProductPhotoID, '.jpg') name, LargePhoto from Production.ProductPhoto
";
$con = New-Object Data.SqlClient.SqlConnection;
$con.ConnectionString = "Data Source=$Server;Integrated Security=True;Initial Catalog=$Database;TrustServerCertificate=true";
$con.Open();
Write-Output ((Get-Date -format yyyy-MM-dd-HH:mm:ss) + ": Started ...");
$cmd = New-Object Data.SqlClient.SqlCommand $Sql, $con;
$cmd.CommandTimeout = 120
$rd = $cmd.ExecuteReader();
While ($rd.Read())
try
Write-Output ("Exporting: 0" -f $rd.GetString(0));
$fs = New-Object System.IO.FileStream ($Dest + $rd.GetString(0)), Create, Write;
$rd.GetStream(1).CopyTo($fs)
$fs.Close()
catch
Write-Output ($_.Exception.Message)
finally
$fs.Dispose();
$rd.Close();
$cmd.Dispose();
$con.Close();
Write-Output ("Finished");
【讨论】:
以上是关于尝试使用 PS 脚本从 SQL 中提取数据的主要内容,如果未能解决你的问题,请参考以下文章
SQL Alchemy - 从 Oracle 迁移到 MySQL 的 Python 脚本