You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell插入Azure SQL报错:无法将PSObject转换为Byte[]

PowerShell插入JSON到Azure SQL数据库报错排查与解决

问题根源

你遇到的错误是因为直接将ConvertFrom-Json生成的PSObject赋值给了@JsonContent参数:SQL Server的.NET客户端无法将PSObject类型直接转换为nvarchar(max)对应的字符串类型,导致类型转换失败;而用$jsonContent.ToString()得到空字符串,是因为PowerShell自定义对象(PSObject)的默认ToString()方法只会返回空字符串或类型名称,不会自动序列化回JSON格式。

解决方案

有两种可靠方式获取可插入的JSON字符串:

方法1:直接读取JSON文件原始文本(推荐)

跳过不必要的反序列化/序列化步骤,直接读取文件原始内容,既能保留JSON原始格式,又避免性能损耗:

Get-ChildItem -Path $jsonFilesPath -Filter *.json | ForEach-Object {
    # 读取文件完整原始文本
    $rawJson = Get-Content $_.FullName -Raw
    # 仅反序列化一次用于提取P1、P2属性
    $jsonObject = $rawJson | ConvertFrom-Json -Depth 100

    $Command.Parameters["@P1"].Value = $jsonObject.P1
    $Command.Parameters["@P2"].Value = $jsonObject.P2
    # 直接使用原始JSON文本赋值
    $Command.Parameters["@JsonContent"].Value = $rawJson

    $Command.ExecuteNonQuery()
    Write-Host "Inserted $($_.FullName) into $table"
}

方法2:将PSObject重新序列化为JSON

如果必须先将JSON转为PSObject处理,可通过ConvertTo-Json重新序列化:

Get-ChildItem -Path $jsonFilesPath -Filter *.json | ForEach-Object {
    $jsonContent = Get-Content $_.FullName | ConvertFrom-Json -Depth 100
    # 重新序列化为JSON字符串,指定Depth避免嵌套层级截断
    $serializedJson = $jsonContent | ConvertTo-Json -Depth 100

    $Command.Parameters["@P1"].Value = $jsonContent.P1
    $Command.Parameters["@P2"].Value = $jsonContent.P2
    $Command.Parameters["@JsonContent"].Value = $serializedJson

    $Command.ExecuteNonQuery()
    Write-Host "Inserted $($_.FullName) into $table"
}

额外优化点

  • 连接字符串避免换行,写成单行:
    $Connection.ConnectionString = "Server=$server;Database=$database;User ID=$username;Password=$password;Trusted_Connection=False;"
    
  • 简化连接打开逻辑:
    if ($Connection.State -ne 'Open') {
        $Connection.Open()
    }
    

修改后完整代码(方法1)

$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = "Server=$server;Database=$database;User ID=$username;Password=$password;Trusted_Connection=False;"

if ($Connection.State -ne 'Open') {
    $Connection.Open()
}

$insertStatement = "INSERT INTO $table (P1, P2, JsonContent) VALUES (@P1, @P2, @JsonContent)"

$Command = New-Object System.Data.SqlClient.SqlCommand($insertStatement, $Connection)
$Command.Parameters.Add("@P1", [System.Data.SqlDbType]::VarChar, 250)
$Command.Parameters.Add("@P2", [System.Data.SqlDbType]::VarChar, 250)
$Command.Parameters.Add("@JsonContent", [System.Data.SqlDbType]::NVarChar, -1)

Get-ChildItem -Path $jsonFilesPath -Filter *.json | ForEach-Object {
    $rawJson = Get-Content $_.FullName -Raw
    $jsonObject = $rawJson | ConvertFrom-Json -Depth 100

    $Command.Parameters["@P1"].Value = $jsonObject.P1
    $Command.Parameters["@P2"].Value = $jsonObject.P2
    $Command.Parameters["@JsonContent"].Value = $rawJson

    $Command.ExecuteNonQuery()
    Write-Host "Inserted $($_.FullName) into $table"
}

$Connection.Close()

内容的提问来源于stack exchange,提问作者WindSwept

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 16:43:11