2013-07-01 3 views
2

Вот моя настройка: в моей схеме у меня есть хранимая процедура (показана ниже), которая вставляет фиктивную строку (для тестирования) в удаленную таблицу. Таблица MY_REMOTE_TABLE является синонимом, указывающим на правильную удаленную таблицу.SQL Server: удаленная вставка таблицы не удалась

Я могу успешно запросить его как

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

У меня есть немного больше информации. Я распечатал свойства ERROR_ *. Ошибка, которую я получаю, - 7395: невозможно запустить вложенную транзакцию для поставщика OLE DB «SQLNCLI10» для связанного сервера «MyLinkedServer». Вложенная транзакция требовалась, потому что для параметра XACT_ABORT установлено значение OFF. Не знаете, что делать с этим ... какие-нибудь идеи? – BaseBallBatBoy

ответ

1

Посмотрите здесь: http://msdn.microsoft.com/de-de/library/ms188792.aspx

Короткая версия:

XACT_ABORT должно быть установлено ПО для операторов модификации данных в явной или неявной транзакции по отношению к большинству поставщиков OLE DB, включая SQL Server. Единственный случай, когда эта опция не требуется - если поставщик поддерживает вложенные транзакции.

Вставьте в начале хранимой процедуры SET XACT_ABORT ON.

+0

спасибо! это работает! – BaseBallBatBoy