这是我的设置:在我的架构中,我有一个存储过程(如下所示),它将一个虚拟行(用于测试)插入到远程表中。表MY_REMOTE_TABLE
是指向正确远程表的同义词。
我可以像
一样成功查询SELECT * FROM MY_REMOTE_TABLE;
在我的本地系统上。这确实有效。
因此,对于测试,我创建了一个带有虚拟测试值的过程,如果该行是远程表的新行,则应该将其插入到远程表中。提示:远程表在插入时是空的,所以它确实应该执行插入。
但总是失败给我一个-6的返回值。我不知道-6代表什么,甚至错误是什么。我只有-6,我知道没有任何东西会被插入到远程表中。有趣的是,当我将insert语句复制到远程服务器时,将同义词替换为远程计算机上的实际表名并执行,它可以正常工作。
所以我真的迷失在这里寻求你的帮助!
CREATE PROCEDURE [dbo].[my_Procedure]
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN DISTRIBUTED TRANSACTION
-- LEFT JOIN AND WHERE NULL WILL ONLY FIND NEW RECORDS -> THEREFORE INSERT INTO TARGET REMOTE TABLE
INSERT INTO MY_REMOTE_TABLE
(--id is not needed because it's an IDENTITY column
user_id,
customer_id,
my_value, year,
Import_Date, Import_By, Change_Date, Change_By)
SELECT
Source.user_id,
Source.customer_id,
Source.my_value,
Source.year,
Source.Import_Date,
Source.Import_By,
Source.Change_Date,
Source.Change_By
FROM
(SELECT
null as id,
126616 as user_id,
17 as customer_id,
0 as my_value,
2012 as year,
GETDATE() AS Import_Date,
'test' AS Import_By,
GETDATE() AS Change_Date,
'test' AS Change_By) AS Source
LEFT JOIN
MY_REMOTE_TABLE AS Target ON Target.id = Source.id
AND Target.user_id = Source.user_id
AND Target.customer_id = Source.customer_id
AND Target.year = Source.year
WHERE
Target.id IS NULL; -- BECAUSE OF LEFT JOIN NEW RECORDS WILL BE NULL, SO WE ONLY SELECT THEM FOR THE INSERT !!!
IF (@@TRANCOUNT > 0 AND XACT_STATE() = 1)
BEGIN
COMMIT TRANSACTION
END
END TRY
BEGIN CATCH
IF (@@TRANCOUNT > 0AND XACT_STATE() = -1)
ROLLBACK TRANSACTION
END CATCH;
END
与此相关的另一个问题。如果我的插入会违反我的远程表上的FK约束,我怎么能设法将错误消息从远程数据库服务器提升到我的本地程序来捕获它?
答案 0 :(得分:1)
请看这里:http://msdn.microsoft.com/de-de/library/ms188792.aspx
简短版本:
对于数据修改语句,必须将XACT_ABORT设置为ON 针对大多数OLE DB提供程序的隐式或显式事务, 包括SQL Server。唯一不需要此选项的情况 是提供者是否支持嵌套事务。
因此,在存储过程的开头插入SET XACT_ABORT ON
。