T-SQL Stored Procedure with While Loop causing Errors in Primary Key Constraints
So I have this MS SQL Stored Procedure:
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
SELE开发者_开发知识库CT 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
But I get an error message on just a very few of the items, it says
Msg 2627, Level 14, State 1, Procedure Import_Agent_Client_Bucket_2010, Line 71 Violation of PRIMARY KEY constraint 'Client_Bucket_Client_PK'. Cannot insert duplicate key in object 'dbo.Client_Bucket_Client'. The statement has been terminated.
EDIT:
OK, I see what you're doing there, I apologize for missing the OUTPUT statement. Based on that information, it seems like the code could break if a record is not inserted into the Client table in the line right before SELECT @Client_GUID = myNewPK FROM @myNewPKTable. If no record is inserted, you would wind up grabbing the GUID from the previous record and when you go to insert that it would cause the PK violation. You might have to check to make sure that records are being inserted into the Client table.
ORIGINAL ANSWER:
It looks like you're declaring a table:
DECLARE @myNewPKTable TABLE (myNewPK UNIQUEIDENTIFIER)
But then you never put anything into it, so this statement must return null:
SELECT @Client_GUID = myNewPK FROM @myNewPKTable
EDIT:
Why not just do this? I don't see why the table @myNewPKTable is even being created.
SET @Client_GUID = NEWID()
EDIT:
I think the reason you are getting the primary key violation is because @Client_Bucket_GUID is null. At the beginning of the procedure, there is this code:
-- 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
After this code is run @Client_Bucket_GUID will always be null. Again, you would have to insert records into @cbPKTable if you wanted to get anything out of it. If you're trying to create a new UNIQUEIDENTIFIER and store it in @Client_Bucket_GUID, just use the NEWID() function.
精彩评论