sql-server 如何通过PowerShell将Web服务数据流式传输到SQL Server VarBinary列中

5uzkadbs  于 2022-10-31  发布在  Shell
关注(0)|答案(1)|浏览(134)

我们在PowerShell中有一个工作解决方案,用于将Web服务(WS)数据a * 流 * a到数据类型为NVARCHAR(max)的SQL Server 2019**表中。此WS数据只是Json格式的业务数据。我希望增强此解决方案,使其也能够将WS数据流到VARBINARY(max)列中。

当前工作代码如下所示(缩写):

$SQL_ImpInsert = @"
Insert Into [Database].dbo.ImportTable  (SeqNo, BulkDataNVarChar)
Values  (@SeqNo, @WSData)
"@

# Create the SQL objects.

$SQLConn = New-Object System.Data.SqlClient.SqlConnection $ConnStr
$SQLConn.Open() 

$SQLCommand = $SQLConn.CreateCommand()
$SQLCommand.CommandText = $SQL_ImpInsert 

# Prep the stream

$WS_URL = 'https://a_valid_ws_request'

$WebRequest = [System.Net.WebRequest]::Create($WS_URL)
$WebRequest.ClientCertificates.Add($WS_Cert) | Out-Null
$WebRequest.Method = "Get"

$WebResponse  = $WebRequest.GetResponse()
$WebStream    = $WebResponse.GetResponseStream()
$WebStreamRdr = New-Object System.IO.StreamReader $WebStream

# Prep the SQL command to use the stream

$SeqNo = 1

$SQLCommand.Parameters.Clear()
$SQLCommand.Parameters.Add("@SeqNo",  [Data.SQLDBType]::INT, -1).Value = $SeqNo
$SQLCommand.Parameters.Add("@WSData", [Data.SQLDBType]::NVARCHAR, -1).Value = $WebStreamRdr

# Perform the streamed insert from the WS into the SQL table

$ExecOutput = $SQLCommand.ExecuteNonQuery();

为了尝试增强解决方案,我向表中添加了一个VARBINARY列,并将命令参数的数据类型更改为VARBINARY,如下所示(仅显示了对以上代码的更改):

$SQL_ImpInsert = @"
Insert Into [Database].dbo.ImportTable  (SeqNo, BulkDataBlob)
Values  (@SeqNo, @WSData)
"@

$SQLCommand.Parameters.Add("@WSData", [Data.SQLDBType]::VARBINARY, -1).Value = $WebStreamRdr

当我运行PowerShell脚本的新版本时,在ExecuteNonQuery语句中出现以下错误:
使用“0”个参数调用“ExecuteNonQuery”时发生异常:“无法将参数值从StreamReader转换为Byte[]。”
我已经查看了命令参数。添加参数,看看是否有需要调整的地方。Add方法有一些变化,但我不知道\认为它们是相关的。
我对流调用的了解不够,不知道是否有什么需要调整的地方。因为我只是改变了目标SQL列的数据类型,所以我希望流的设置保持不变。
我检查了WS数据,应该没有任何大于SQL数据类型VARBINARY可以处理的数据。我不认为这个错误与传入的数据大小有任何关系。
关于如何调整这段代码以将WS数据流传输到VARBINARY参数进而传输到SQL列,您有什么想法吗?

xxls0lw8

xxls0lw81#

StreamReader实现了一个TextReader,它提供了一个无法转换为varbinary字节数组的字符串。我猜您使用nvarchar的第一个示例会成功,因为您得到了字符串的隐式转换。
您可以重构该字符串,使其完全不使用StreamReader,但要回答以下问题,您需要将该字符串转换为字节数组:

$output = $WebStreamRdr.ReadToEnd() # todo: flush & close 
$bytes = [system.Text.Encoding]::UTF8.GetBytes($output)

然后使用$bytes:

$SQLCommand.Parameters.Add("@WSData", [Data.SQLDBType]::VARBINARY, -1).Value = $bytes

您还可以像以前一样将字符串传递到命令中:

$SQLCommand.Parameters.Add("@WSData", [Data.SQLDBType]::NVARCHAR, -1).Value = $WebStreamRdr

然后让命令将其转换为varbinary

$SQL_ImpInsert = @"
Insert Into [Database].dbo.ImportTable  (SeqNo, BulkDataBlob)
Values  (@SeqNo, cast(@WSData as varbinary(max)))
"@

相关问题