2

这是我的设置:在我的架构中,我有一个存储过程(如下所示),它将一个虚拟行(用于测试)插入到远程表中。该表MY_REMOTE_TABLE是指向正确远程表的同义词。

我可以像这样成功地查询它

SELECT * FROM MY_REMOTE_TABLE;

在我的本地系统上。这确实有效。

因此,为了进行测试,我创建了一个包含虚拟测试值的过程,如果该行是远程表的新行,则应将其插入远程表中。提示:插入时远程表是空的,所以它确实应该执行插入。

但它总是无法给我一个返回值-6。我不知道 -6 代表什么,甚至不知道错误可能是什么。我只有 -6 并且我知道不会将任何内容插入远程表中。有趣的是,当我将插入语句复制到远程服务器时,将同义词替换为远程机器上的真实表名并执行,一切正常。

所以我真的迷失在这里寻求你的帮助!

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 约束,我如何设法将错误消息从远程 DB 服务器提升到我的本地过程以捕获它?

4

1 回答 1

1

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

精简版:

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

SET XACT_ABORT ON所以在存储过程的开头插入 a 。

于 2013-07-01T08:46:21.853 回答