SQL Server:远程表插入失败

时间:2013-07-01 07:30:35

标签: sql sql-server stored-procedures

这是我的设置:在我的架构中,我有一个存储过程(如下所示),它将一个虚拟行(用于测试)插入到远程表中。表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约束,我怎么能设法将错误消息从远程数据库服务器提升到我的本地程序来捕获它?

1 个答案:

答案 0 :(得分:1)

请看这里:http://msdn.microsoft.com/de-de/library/ms188792.aspx

简短版本:

  

对于数据修改语句,必须将XACT_ABORT设置为ON   针对大多数OLE DB提供程序的隐式或显式事务,   包括SQL Server。唯一不需要此选项的情况   是提供者是否支持嵌套事务。

因此,在存储过程的开头插入SET XACT_ABORT ON