Хранимая процедура T-SQL с циклом while, вызывающим ошибки в ограничениях первичного ключа - PullRequest
0 голосов
/ 20 февраля 2011

Итак, у меня есть хранимая процедура MS SQL:

ALTER PROCEDURE [dbo].[Import_Agent_Client_Bucket_2010]
AS
BEGIN
    -- Loop Through Each Agent, Create a Bucket, Add their Clients to the Bucket
    DECLARE Agent_Cursor CURSOR FOR
    SELECT Agent_GUID, Agent_ID
    FROM  realforms_2011.dbo.Agent

    DECLARE @Agent_GUID uniqueidentifier
    DECLARE @Agent_ID int

    OPEN Agent_Cursor;
    FETCH NEXT FROM Agent_Cursor
    INTO @Agent_GUID, @Agent_ID;

    WHILE @@FETCH_STATUS = 0
        BEGIN
            -- Create a bucket for each agent
            DECLARE @cbPKTable TABLE (cbPK UNIQUEIDENTIFIER, cbID int) 

            INSERT INTO realforms_2011.dbo.Client_Bucket ([Description] ) OUTPUT inserted.Client_Bucket_GUID, inserted.Client_Bucket_ID INTO @cbPKTable
            SELECT ISNULL(a.First_Name, ' ') + ' ' + ISNULL(a.Last_Name, ' ') + '''s Clients'
            FROM  realforms_2011.dbo.Agent a
            WHERE Agent_GUID = @Agent_GUID

            DECLARE @Client_Bucket_GUID uniqueidentifier
            SELECT @Client_Bucket_GUID = cbPK FROM @cbPKTable

            DECLARE @Client_Bucket_ID int
            SELECT @Client_Bucket_ID = cbID FROM @cbPKTable

            INSERT INTO realforms_2011.dbo.Agent_Client_Bucket (Agent_GUID, Agent_ID, Client_Bucket_GUID, Client_Bucket_ID)
            VALUES (@Agent_GUID, @Agent_ID, @Client_Bucket_GUID, @Client_Bucket_ID)

            DECLARE @Client_GUID uniqueidentifier
            DECLARE @Client_ID int

            -- Get clients from the server (2010)
            DECLARE Client_Cursor CURSOR FOR
            SELECT C.Client_ID
            FROM realforms.dbo.Client C
                INNER JOIN realforms.dbo.Agent_Client AC ON AC.Client_ID = C.Client_ID
            WHERE AC.Agent_ID = @Agent_ID 
            ORDER BY C.Client_ID ASC

            OPEN Client_Cursor;
            FETCH NEXT FROM Client_Cursor
            INTO @Client_ID
            -- loop through each 2010 client
            WHILE @@FETCH_STATUS = 0
            BEGIN
                DECLARE @myNewPKTable TABLE (myNewPK UNIQUEIDENTIFIER) 

                INSERT INTO realforms_2011.dbo.Client (Client_ID,Name,Secondary_Name,[Address],Address_2,City_State_Zip,Phone,Email_Address,Secondary_Email_Address,Create_Date,Last_Change_Date,[Status],File_Under,[Year]) OUTPUT inserted.Client_GUID INTO @myNewPKTable
                SELECT c.Client_ID,Name,Secondary_Name,[Address],Address_2,City_State_Zip,Phone,Email_Address,Secondary_Email_Address,Create_Date,Last_Change_Date,[Status],File_Under,2010
                FROM realforms.dbo.Client C
                    INNER JOIN realforms.dbo.Agent_Client AC ON AC.Client_ID = C.Client_ID
                WHERE AC.Agent_ID = @Agent_ID AND C.Client_ID = @Client_ID

                SELECT @Client_GUID = myNewPK FROM @myNewPKTable

                INSERT INTO realforms_2011.dbo.Client_Bucket_Client (Client_Bucket_GUID, Client_GUID, Client_ID, Client_Bucket_ID, [Year])
                VALUES (@Client_Bucket_GUID, @Client_GUID, @Client_ID, @Client_Bucket_ID, 2010)

                PRINT 'Client Bucket GUID: '
                PRINT @Client_Bucket_GUID
                PRINT 'Client GUID: '
                PRINT @Client_GUID

                FETCH NEXT FROM Client_Cursor
                INTO @Client_ID;
            END;

            CLOSE Client_Cursor;
            DEALLOCATE Client_Cursor;

            FETCH NEXT FROM Agent_Cursor
            INTO @Agent_GUID, @Agent_ID;
       END;
    CLOSE Agent_Cursor;
    DEALLOCATE Agent_Cursor;

END

Но я получаю сообщение об ошибке только по очень немногим элементам, оно говорит

Сообщение 2627,Уровень 14, состояние 1, процедура Import_Agent_Client_Bucket_2010, строка 71 Нарушение ограничения PRIMARY KEY 'Client_Bucket_Client_PK'.Невозможно вставить дубликат ключа в объект 'dbo.Client_Bucket_Client'.Заявление было прекращено.

1 Ответ

0 голосов
/ 20 февраля 2011

РЕДАКТИРОВАТЬ:

ОК, я вижу, что вы там делаете, я прошу прощения за то, что пропустил оператор OUTPUT.Основываясь на этой информации, кажется, что код может сломаться, если запись не будет вставлена ​​в таблицу Client в строке прямо перед SELECT @Client_GUID = myNewPK FROM @myNewPKTable.Если никакая запись не вставлена, вы в конечном итоге получите GUID из предыдущей записи, и когда вы собираетесь вставить, это вызовет нарушение PK.Возможно, вам придется проверить, чтобы убедиться, что записи вставляются в таблицу клиента.

ОРИГИНАЛЬНЫЙ ОТВЕТ:

Похоже, вы объявляете таблицу:

DECLARE @myNewPKTable TABLE (myNewPK UNIQUEIDENTIFIER)

Но тогда вы никогда ничего не вкладываете в нее, поэтомуэтот оператор должен возвращать нуль:

SELECT @Client_GUID = myNewPK FROM @myNewPKTable

РЕДАКТИРОВАТЬ:

Почему бы просто не сделать это?Я не понимаю, почему таблица @myNewPKTable даже создается.

SET @Client_GUID = NEWID()

РЕДАКТИРОВАТЬ:

Я думаю, что причиной получения нарушения первичного ключа является то, что @Client_Bucket_GUID равен нулю.В начале процедуры есть этот код:

-- Create a bucket for each agent
DECLARE @cbPKTable TABLE (cbPK UNIQUEIDENTIFIER, cbID int) 

...

DECLARE @Client_Bucket_GUID uniqueidentifier
SELECT @Client_Bucket_GUID = cbPK FROM @cbPKTable

После запуска этого кода @Client_Bucket_GUID всегда будет нулевым.Опять же, вам придется вставлять записи в @cbPKTable, если вы хотите получить что-нибудь из этого.Если вы пытаетесь создать новый UNIQUEIDENTIFIER и сохранить его в @Client_Bucket_GUID, просто используйте функцию NEWID ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...