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

PostgreSQL到SQL Server数据迁移脚本执行报错求助

问题解决思路

第一个错误:"System.Data.DataRow.id" 未绑定

这个错误是因为你直接把DataRow对象的属性拼进SQL语句里,PowerShell没有解析出实际字段值,反而把对象的类型和属性名当成了字符串(比如$row.id被转成了System.Data.DataRow.id)。

解决方法:

  • 禁止直接拼接字符串生成SQL,改用参数化查询,既避免SQL注入,又能解决值解析问题。
  • 从DataRow提取实际值时,用索引器$row["列名"]或$row.Item("列名"),确保拿到的是字段值而非对象引用。

第二个错误:表值参数类型无效

使用表值参数批量插入时,SQL Server要求你先在目标库中定义匹配结构的用户定义表类型,不能直接用普通参数名。

解决步骤:

  1. 先在SQL Server中创建对应表类型(假设目标表postgres.DATABASE_TABLE包含id、name等字段):
CREATE TYPE dbo.DATABASE_TABLE_Type AS TABLE (
    id INT,
    name NVARCHAR(100)
    -- 其他字段需和目标表结构完全一致
);
  1. 在PowerShell中指定这个类型名作为表值参数的类型。

完整示例脚本

# 1. 从PostgreSQL查询数据
$pgConnString = "Server=pg_server;Database=pg_db;User Id=pg_user;Password=pg_pass;"
$pgQuery = "SELECT id, name FROM source_table;"
$pgDataAdapter = New-Object System.Data.Odbc.OdbcDataAdapter($pgQuery, $pgConnString)
$dataTable = New-Object System.Data.DataTable
$pgDataAdapter.Fill($dataTable)

# 2. 连接SQL Server并批量插入
$sqlConnString = "Server=sql_server;Database=sql_db;Integrated Security=True;"
$sqlConn = New-Object System.Data.SqlClient.SqlConnection($sqlConnString)
$sqlConn.Open()

# 定义批量插入SQL,使用表值参数
$sqlQuery = @"
INSERT INTO postgres.DATABASE_TABLE (id, name)
SELECT id, name FROM @BatchData;
"@

# 创建SQL命令并配置表值参数
$sqlCmd = New-Object System.Data.SqlClient.SqlCommand($sqlQuery, $sqlConn)
$tvp = New-Object System.Data.SqlClient.SqlParameter("@BatchData", [System.Data.SqlDbType]::Structured)
$tvp.TypeName = "dbo.DATABASE_TABLE_Type" # 必须是你在SQL Server创建的类型名
$tvp.Value = $dataTable # 直接传入PostgreSQL查询得到的DataTable
$sqlCmd.Parameters.Add($tvp)

# 执行插入
try {
    $rowsAffected = $sqlCmd.ExecuteNonQuery()
    Write-Host "成功插入 $rowsAffected 条数据"
} catch {
    Write-Error "插入失败: $_"
} finally {
    $sqlConn.Close()
}

关键注意事项

  • 确保PostgreSQL返回的DataTable结构和SQL Server的用户定义表类型完全匹配(字段名、数据类型、长度一致)。
  • 如果不需要批量插入,单条插入也要用参数化,示例:
foreach ($row in $dataTable.Rows) {
    $sqlQuery = "INSERT INTO postgres.DATABASE_TABLE (id, name) VALUES (@id, @name)"
    $sqlCmd = New-Object System.Data.SqlClient.SqlCommand($sqlQuery, $sqlConn)
    $sqlCmd.Parameters.AddWithValue("@id", $row["id"])
    $sqlCmd.Parameters.AddWithValue("@name", $row["name"])
    $sqlCmd.ExecuteNonQuery()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:15:38