这两天在处理sqlserver通过链接服务器连oracle数据库写入数据到oracle数据库,
在sqlserver的存储过程中,
begin tran
insert oracle.....
commit;
sqlserver 存储过程编译通过,执行是报错: OLE DB 访问接口 "MSDAORA" 无法启动分布式事务
后来在网上搜索资料,有人指出是MSDTC服务设置的问题,
http://www.cnblogs.com/chnking/archive/2007/04/04/699891.html
按照他们的记录修改msdtc服务的设置,还是没有成功 。
后来看到通过执行oracle函数来处理事务
http://topic.csdn.net/t/20060531/12/4790992.html
这个确实可以,但在调用oracle函数时,又出现错误:
ORA-14551: cannot perform a DML operation inside a query
因为sqlserver执行oracle函数时的语句select * from openquery(ora,select funtest from dual)
是一个查询语句,不能在函数中执行插入,提交,回滚等动作。
又找到资料
http://www.cnblogs.com/pengyq/archive/2008/11/26/1341656.html
-----------------------
建立自由性交易, 使用名为autonomous_transaction的编译指示(编译命令,如, #include), 这个编译命令要放在declare里面.
Delcare or replace procedure procedure_name(params, types)
AS
PRAGMA AUTONOMOUS_TRANSACTION;
当程序执行的时候,pl/sql 会把autonomous_transaction当成独立存在的区域来处理.
用途是用在记录程序事件,不影响程序的进行.
---------------------------
在 oracle的函数中加入PRAGMA AUTONOMOUS_TRANSACTION; 终于是可以了。
=============================
最后的流程是:
oracle中的正式表:test
oracle中的临时表:tmptest
oracle中的存储过程:sp_write_test (res out int),将数据从临时表导入到正是表,中间加上事务处理,成功返回1,失败返回0
oracle中的函数:fun_write_tmptest return int,调用存储过程,并将存储过程的输出参数res返回给调用者.
sqlserver的存储过程中先写入到临时表,临时表全部写完后,在调用函数 fun_write_tmptest将数据转入到正式表,
select * from openquery(ora,'select fun_write_tmptest from dual');
保证正式表看到的数据是完整的。