【问题标题】:Powershell SQLConnection JSON Insert works in PS5 but not PS7Powershell SQLConnection JSON Insert 适用于 PS5 但不适用于 PS7
【发布时间】:2021-09-28 08:17:48
【问题描述】:

所以我有一个 powershell 脚本,它调用一个 web api,它以 json 格式返回数据,我在其中将数据推送到 sql server 中的表中。运行时环境是 Windows Server 2016,脚本在 Powershell 5 中运行良好,但是当我在 Powershell 7 中运行脚本时,我遇到数据处理错误,尤其是在名称(或在 POC 字段下方的示例中)这样的数据周围在其中引用。 (即鲍勃·奥康纳)。我尝试了一些方法来转义 sql 中的数据,并希望避免在插入之前解析 PS 中的所有响应。

是否有人知道 PS 5 和 7 之间 sql 客户端的差异会导致数据处理发生这种变化,或者可能是一种简单的修复方法?

这是相关的 PS 代码。

$sqlConn = New-Object System.Data.SqlClient.SqlConnection
$sqlConn.ConnectionString = 'myConnString'
$sqlConn.Open()
$sqlcmd = $sqlConn.CreateCommand()
$sqlcmd.Connection = $sqlConn
$response = Invoke-RestMethod $URL -Method 'GET' -Headers $headers
$respjson = $response | ConvertTo-Json -Depth 10 -Compress
$sqlcmd.CommandText = $InsertStatement -f $respjson
$result = $sqlcmd.ExecuteNonQuery()

这是用于将json记录批量插入表中的sql脚本。

DECLARE @JSON NVARCHAR(MAX);
SET @JSON = N'{0}';
INSERT INTO MyTable
SELECT * FROM OPENJSON (@JSON, N'$.result')
WITH ( 
Location    VARCHAR(10) '$.u_location',
ContactVerified VARCHAR(5)  '$.u_contact_verified',
POCType     VARCHAR(20) '$.u_type_of_poc',
POC         VARCHAR(50) '$.u_poc',
Active      VARCHAR(5)  '$.u_active'
);

【问题讨论】:

  • 您的代码对 SQL 注入开放。而不是在插入语句中将 JSON 复制到 {0} 中,您应该使用 nvarchar(max) SqlParameter,然后您不必考虑转义 ' 字符。
  • @AlwaysLearning 感谢您的反馈。我将审查该建议。我不太担心这一点,因为它是系统 API 的内部系统,但以最安全的方式执行它是有意义的。

标签: json sql-server powershell .net-core


【解决方案1】:

注意:

  • 值得退后一步并考虑AlwaysLearning 的建议:“您的代码对SQL 注入开放。与其在INSERT 语句中将JSON 复制到{0} 中,不如使用@ 987654326@SqlParameter,那么您不必考虑转义' 字符。”

至于你眼前的问题:

虽然 ConvertTo-JsonPowerShell (Core) 7 中的行为原则上可能有所不同(因为底层实现相对于 Windows PowerShell 发生了变化),但听起来您的问题是与此无关:

为了使生成的 SQL 命令在语法上正常工作,您需要将 JSON 字符串中的 ' 字符转义为 ''

$sqlcmd.CommandText = $InsertStatement -f ($respjson -replace "'", "''")

【讨论】:

    【解决方案2】:

    根据以前的答案和 cmets 的反馈。这是我修改后的代码,已转换为 sql 参数以供将来的访问者使用。

    $sqlConn = New-Object System.Data.SqlClient.SqlConnection
    $sqlConn.ConnectionString = 'myConnString'
    $sqlConn.Open()
    $sqlcmd = $sqlConn.CreateCommand()
    $sqlcmd.Connection = $sqlConn
    $response = Invoke-RestMethod $URL -Method 'GET' -Headers $headers
    $respjson = $response | ConvertTo-Json -Depth 10 -Compress
    #$sqlcmd.CommandText = $InsertStatement -f $respjson
    $sqlcmd.CommandText = $InsertStatement
    $sqlcmd.Parameters.Add((New-Object Data.SqlClient.SqlParameter('@JSON', [Data.SqlDbType]::NVarChar, -1))).Value = $respjson
    $sqlcmd.Prepare()
    $result = $sqlcmd.ExecuteNonQuery()
    $sqlcmd.Parameters.Clear()
    

    添加 SQL 文件更新

    INSERT INTO MyTable
    SELECT * FROM OPENJSON (@JSON, N'$.result')
    WITH ( 
    Location   VARCHAR(10) '$.u_location',
    ContactVerified VARCHAR(5)  '$.u_contact_verified',
    POCType     VARCHAR(20) '$.u_type_of_poc',
    POC         VARCHAR(50) '$.u_poc',
    Active      VARCHAR(5)  '$.u_active'
    );
    

    我测试了这种方法和mklement0 推荐的方法,性能大致相同。

    【讨论】:

      猜你喜欢
      • 2011-12-24
      • 2012-08-04
      • 2017-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多