PostgreSQL到SQL Server数据迁移脚本执行报错求助
问题解决思路
第一个错误:"System.Data.DataRow.id" 未绑定
这个错误是因为你直接把DataRow对象的属性拼进SQL语句里,PowerShell没有解析出实际字段值,反而把对象的类型和属性名当成了字符串(比如$row.id被转成了System.Data.DataRow.id)。
解决方法:
- 禁止直接拼接字符串生成SQL,改用参数化查询,既避免SQL注入,又能解决值解析问题。
- 从
DataRow提取实际值时,用索引器$row["列名"]或$row.Item("列名"),确保拿到的是字段值而非对象引用。
第二个错误:表值参数类型无效
使用表值参数批量插入时,SQL Server要求你先在目标库中定义匹配结构的用户定义表类型,不能直接用普通参数名。
解决步骤:
- 先在SQL Server中创建对应表类型(假设目标表
postgres.DATABASE_TABLE包含id、name等字段):
CREATE TYPE dbo.DATABASE_TABLE_Type AS TABLE ( id INT, name NVARCHAR(100) -- 其他字段需和目标表结构完全一致 );
- 在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
相关产品推荐
相关产品推荐

