Sybase SQL Anywhere到MSSQL数据复制:关联更新报错求助
问题原因
当你用本地SQLA表关联远程MSSQL代理表执行UPDATE时,SQL Anywhere无法把这种跨数据源的关联逻辑完整下推到MSSQL执行。代理表的更新要求查询能被远程数据库直接处理,但本地表和代理表的关联需要在SQLA本地做数据匹配,这种混合查询不属于可更新的远程查询范畴,因此触发报错。
解决方案
方案1:拆分操作,用临时表中转
先把需要更新的匹配关系提取到本地临时表,再基于临时表更新代理表:
- 生成待更新的数据集到临时表:
SELECT Test.ID AS OldID, S.accno AS NewID, S.particulars AS NewName INTO #TempUpdates FROM "DBA"."acc_ledgers" S JOIN Test ON S.accno <> Test.ID
- 基于临时表批量更新代理表:
UPDATE Test SET ID = tu.NewID, Name = tu.NewName FROM Test JOIN #TempUpdates tu ON Test.ID = tu.OldID
如果上述批量更新仍报错,改用游标逐行处理(适合数据量不大的场景):
DECLARE @OldID INT, @NewID INT, @NewName VARCHAR(100) DECLARE upd_cur CURSOR FOR SELECT OldID, NewID, NewName FROM #TempUpdates OPEN upd_cur FETCH NEXT FROM upd_cur INTO @OldID, @NewID, @NewName WHILE @@FETCH_STATUS = 0 BEGIN UPDATE Test SET ID = @NewID, Name = @NewName WHERE ID = @OldID FETCH NEXT FROM upd_cur INTO @OldID, @NewID, @NewName END CLOSE upd_cur DEALLOCATE upd_cur DROP TABLE #TempUpdates
方案2:用远程存储过程执行更新
在MSSQL端创建处理更新的存储过程,然后在SQLA中调用:
- MSSQL端创建存储过程:
CREATE PROCEDURE UpdateTest @OldID INT, @NewID INT, @NewName VARCHAR(100) AS BEGIN UPDATE Test SET ID = @NewID, Name = @NewName WHERE ID = @OldID END
- 在SQLA中创建该存储过程的代理对象,然后通过游标循环调用(逻辑同方案1的游标部分,只是把UPDATE换成存储过程调用)。
方案3:使用SQL Anywhere官方同步工具
如果是长期的同步需求,建议用SQL Anywhere自带的MobiLink或SQL Remote工具:
- MobiLink适合服务器到服务器的双向同步,支持冲突检测与解决;
- SQL Remote适合点对点的同步场景。
这些工具专门针对跨数据库同步设计,比手动写代理表更新更稳定可靠。
内容的提问来源于stack exchange,提问作者FaheemMCFC
相关产品推荐
相关产品推荐

