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

SQL Server经ODBC链接服务器插入PostgreSQL报无法识别插入行错误

问题根因

报错核心是SQL Server通过MSDASQL OLEDB提供程序调用PostgreSQL ODBC驱动执行写操作时,驱动无法为写入目标生成唯一行标识,无法完成写入后的行确认流程。SELECT操作不需要行级定位校验,因此可以正常运行。你当前OpenQuery写入目标为视图(名称带_v1后缀),是触发该问题的最常见诱因。

可行解决方案

方案1:调整链接服务器配置,直接写入物理表

不要将视图作为OpenQuery的写入目标,替换为视图对应的底层物理表,先执行以下命令配置链接服务器参数:

-- 开启高级配置选项
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'Ad Hoc Distributed Queries', 1;
RECONFIGURE;

-- 关闭分布式事务升级,开启非事务写入
EXEC master.dbo.sp_serveroption 
    @server = N'DDL_PUYAML1_64', 
    @optname = N'remote proc transaction promotion', 
    @optvalue = N'false';
EXEC master.dbo.sp_serveroption 
    @server = N'DDL_PUYAML1_64', 
    @optname = N'data access', 
    @optvalue = N'true';
EXEC master.dbo.sp_serveroption 
    @server = N'DDL_PUYAML1_64', 
    @optname = N'non transacted updates', 
    @optvalue = N'true';

配置完成后通过四部分名称直接写入物理表,替换代码中的schema和表名为PG端实际值:

INSERT INTO [DDL_PUYAML1_64].[ws_sls_core].[实际schema名].[实际物理表名]
(sn1, encl, encl_model)
SELECT sn1,encl,encl_model FROM #temp1

注意:PostgreSQL默认schema通常为public,不要直接对视图执行分布式写入,绝大多数版本的PostgreSQL ODBC驱动无法为视图自动生成唯一行标识。

方案2:通过OPENQUERY执行原生PG写入语句,绕过MSDASQL行校验

放弃INSERT INTO OPENQUERY(...) SELECT ...的写法,直接把INSERT逻辑放到远端执行,完全在PG端完成写入操作,不会触发MSDASQL的行识别校验。小数据量可以直接拼接SQL执行:

DECLARE @insertSql NVARCHAR(MAX);
SELECT @insertSql = STRING_AGG(
    N'INSERT INTO ws_sls_core.dd_enclosures_forarsdashboard_v1(sn1,encl,encl_model) VALUES ('
    + '''' + REPLACE(CAST(sn1 AS NVARCHAR(MAX)),'''','''''') + ''','
    + '''' + REPLACE(CAST(encl AS NVARCHAR(MAX)),'''','''''') + ''','
    + '''' + REPLACE(CAST(encl_model AS NVARCHAR(MAX)),'''','''''') + ''''
    +');',
    N''
)
FROM #temp1;

EXEC (@insertSql) AT [DDL_PUYAML1_64];

如果数据量较大,可以拆成每1000行一批执行,避免单条SQL过长。如果PG端的视图配置了INSTEAD OF触发器,这个写法可以正常写入视图,不需要操作底层物理表。

方案3:调整PostgreSQL ODBC驱动配置

打开Windows系统的64位ODBC数据源管理器,找到链接服务器使用的PostgreSQL DSN,进入配置页修改以下参数:

  • 勾选 True is -1 选项
  • 取消勾选 Use Declare/Fetch 选项
  • 勾选 Updatable Cursors 选项
  • 将 Level of rollback on errors 设置为 Transaction
    保存配置后重启SQL Server服务,再测试写入操作。

方案4:替换桥接驱动

MSDASQL是ODBC转OLEDB的桥接层,本身对PostgreSQL写操作兼容性很差,可以替换为PostgreSQL原生OLEDB提供程序,配置链接服务器时直接选择原生PG OLEDB驱动,不走ODBC桥接,从根源上避免这类行识别报错。

避坑说明
  • 分布式写入PG时不要开启MS DTC分布式事务,PG ODBC驱动对DTC兼容性极差,极易触发校验失败
  • 写入字段的数据类型必须和PG端定义完全匹配,字符串、整数、时间类型的隐式转换问题也可能偶发同类报错
  • 不要在OpenQuery的SELECT子句中使用不带主键/唯一约束的表或视图,驱动无法生成稳定的行定位标识

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:30:53