SQL SCOPE_IDENTITY或OUTPUT包含来自另一个表的数据

时间:2014-02-06 23:38:07

标签: sql sql-server tsql

我试图从群发插入中获取每行的ID,并使用临时表#InsertedClients中的ID创建映射表。我使用相同的临时表进行初始插入,但PDATClientID不是插入的一部分。我似乎无法弄清楚如何正确地做到这一点。当我使用SCOPE_IDENTITY插入Client_Mapping表时,它只从第一个插入中获取ID并将其与所有PDATClientID一起放入。在做了很多谷歌搜索之后我相信我应该使用OUTPUT,但似乎无法计算如何将每个记录的INSERTED.CLID与每个PDATClientID放在一起。我还应该说我不能使用游标,因为行太多了。非常感谢任何帮助!

            IF NOT EXISTS (
                            SELECT ID
                            FROM sysobjects
                            WHERE id = object_id(N'[Client_Mapping]')
                                AND OBJECTPROPERTY(id, N'IsUserTable') = 1
                            )
                        CREATE TABLE [Client_Mapping] (
                            ClientMappingID INT Identity(1, 1) NOT NULL
                            ,PDATClientID INT NOT NULL
                            ,CLID INT NOT NULL
                            ,AUDITDATE DATETIME NOT NULL
                            ,CONSTRAINT [PK_Client_Mapping] PRIMARY KEY (ClientMappingID)
                            )

            -- Begin Inserts

            SELECT 
                First_Name
                ,Middle_Name
                ,Last_Name
                ,CONVERT(DATETIME, Date_Of_Birth) AS DOB
                ,a.Address_Line as Address1 
                ,a.Address_Line_2 as Address2 
                ,a.Zip_Code as  ZipCode -- ??? Do I need to account for zipcode + 4  
                ,REPLACE(REPLACE(REPLACE(cphp.Number_Or_Address, '(', ''), ')', '-'), ' ', '') AS HomePhone
                ,REPLACE(REPLACE(REPLACE(cpcp.Number_Or_Address, '(', ''), ')', '-'), ' ', '') AS CellPhone
                ,cpem.Number_Or_Address AS EMAIL
                ,c.Client_ID as PDATClientID
                ,c.Action AS [ClientAction]
                ,ca.Action as [ClientAddressAction]
                ,a.Action AS [AddressAction]
                ,cphp.Action AS [HomePhoneAction]
                ,cpcp.Action AS [CellPhoneAction]
                ,cpem.Action AS [EmailAction]

            INTO #InsertClients 

            FROM Client c
            LEFT JOIN Client_Address ca ON ca.Client_ID = c.Client_ID
            LEFT JOIN Address a ON a.Address_ID = ca.Address_ID
            LEFT JOIN Client_Phone cphp ON cphp.Client_ID = c.Client_ID
                AND cphp.Phone_Email_Type = 'HP'
                AND cphp.Start_Date = (
                    SELECT MAX(Start_Date)
                    FROM Client_Phone
                    WHERE Client_ID = c.Client_ID
                    )
            LEFT JOIN Client_Phone cpcp ON cpcp.Client_ID = c.Client_ID
                AND cpcp.Phone_Email_Type = 'CP'
                AND cpcp.Start_Date = (
                    SELECT MAX(Start_Date)
                    FROM Client_Phone
                    WHERE Client_ID = c.Client_ID
                    )
            LEFT JOIN Client_Phone cpem ON cpem.Client_ID = c.Client_ID
                AND cpem.Phone_Email_Type = 'EM'
                AND cpem.Start_Date = (
                    SELECT MAX(Start_Date)
                    FROM Client_Phone
                    WHERE Client_ID = c.Client_ID
                    )
            where c.action ='I' 


            BEGIN TRY
                    BEGIN TRAN

                    INSERT INTO [dbo].[Clients] (
                        [FName]
                        ,[MiddleInitial]
                        ,[LName]
                        ,[DOB]
                        ,[Address1]
                        ,[Address2]
                        ,[ZipCode]
                        ,[HomePhone]
                        ,[CellPhone]
                        ,[Email]
                        ,[AuditStaffID]
                        ,[AuditDate]
                        ,[DateCreated]
                        )
                        Select
                        First_Name
                        ,CASE when Middle_Name = '' THEN NULL ELSE Middle_Name END
                        ,Last_Name
                        ,DOB
                        ,Address1
                        ,Address2
                        ,ZipCode
                        ,HomePhone
                        ,CellPhone
                        ,EMail
                        ,496 AS [AuditStaffID]
                        ,CURRENT_TIMESTAMP AS [AuditDate]
                        ,CURRENT_TIMESTAMP AS [DateCreated]
                        FROM
                        #InsertClients
                        Where
                        [ClientAction] = 'I'



                        INSERT INTO [Client_Mapping]
                        (
                        PDATClientID
                        ,CLID
                        ,AUDITDATE
                        )
                        SELECT
                        PDATClientID
                        ,SCOPE_IDENTITY()
                        ,CURRENT_TIMESTAMP
                        FROM #InsertClients


                    COMMIT

                    END TRY

                    BEGIN CATCH

                        ROLLBACK

                    SELECT ERROR_NUMBER() AS ErrorNumber
                        ,ERROR_SEVERITY() AS ErrorSeverity
                        ,ERROR_STATE() AS ErrorState
                        ,ERROR_PROCEDURE() AS ErrorProcedure
                        ,ERROR_LINE() AS ErrorLine
                        ,ERROR_MESSAGE() AS ErrorMessage

                    END CATCH

2 个答案:

答案 0 :(得分:0)

你的问题中有一个地狱代码我可以用几行解释你如何检索所有插入的id。

是SCOPE_IDENTITY()为您提供标识列生成的最后一个IDENTITY值。在这种情况下,您需要使用表变量来获取插入期间生成的所有Identity值

/* Declare a table Vairable */

DECLARE @NewValues TABLE (IDs INT);

/* In Your Insert Statement use OUTPUT clause */

INSERT INTO Table_Name (Column1,Column2,Column3,....)
OUTPUT inserted.Identity_Column   INTO @NewValues (IDs)
SELECT Column1,Column2,Column3,....
FROM Table_Name2

/* Finally Select values from your table variable  */

SELECT * FROM @NewValues

您的查询

在您的情况下,您的插入语句应该类似于......

INSERT INTO [dbo].[Clients] (
[FName]
,[MiddleInitial]
,[LName]
,[DOB]
,[Address1]
,[Address2]
,[ZipCode]
,[HomePhone]
,[CellPhone]
,[Email]
,[AuditStaffID]
,[AuditDate]
,[DateCreated]
)
OUTPUT inserted.[FName], inserted.[MiddleInitial] ,.... INTO @TableVarible(First_Name,[MiddleInitial].....) 

Select
First_Name
,CASE when Middle_Name = '' THEN NULL ELSE Middle_Name END
,Last_Name
,DOB
,Address1
,Address2
,ZipCode
,HomePhone
,CellPhone
,EMail
,496 AS [AuditStaffID]
,CURRENT_TIMESTAMP AS [AuditDate]
,CURRENT_TIMESTAMP AS [DateCreated]
FROM
#InsertClients
Where
[ClientAction] = 'I'

答案 1 :(得分:0)

使用此处的示例解决了问题:http://sqlserverplanet.com/tsql/match-identity-columns-after-insert。该网站的示例如下。

         -- Drop temp tables if they already exist
         IF OBJECT_ID('TempDB..#source', 'U') IS NOT NULL DROP TABLE #source;
         IF OBJECT_ID('TempDB..#target', 'U') IS NOT NULL DROP TABLE #target;
         IF OBJECT_ID('TempDB..#xref', 'U') IS NOT NULL DROP TABLE #xref;
         GO

         -- Create the temp tables
         CREATE TABLE #source (id INT PRIMARY KEY IDENTITY(1, 1), DATA INT);
         CREATE TABLE #target (id INT PRIMARY KEY IDENTITY(1, 1), DATA INT);
         CREATE TABLE #xref (ROW INT PRIMARY KEY IDENTITY(1, 1), source_id INT, target_id INT);
         GO

         -- If xref table is being reused, make sure to clear data and reseed by truncating.
         TRUNCATE TABLE #xref;

         -- Fill source table with dummy data (even numbers)
         INSERT INTO #source (DATA)
         SELECT 2 UNION SELECT 4 UNION SELECT 6 UNION SELECT 8;
         GO

         -- Fill target table with dummy data (odd numbers) to simulate existing records
         INSERT INTO #target (DATA)
         SELECT 1 UNION SELECT 3 UNION SELECT 5;
         GO

         -- Insert source table data into target table.  IMPORTANT: Inserted data must be sorted by the source table's primary key.
         INSERT INTO #target (DATA)
         OUTPUT INSERTED.id INTO #xref (target_id)
         SELECT DATA 
         FROM #source
         ORDER BY id ASC;
         GO

         -- Update the xref table with the PK of the source table.  This technique is used for data not captured during the insert.
         ;WITH src AS (SELECT id, ROW = ROW_NUMBER() OVER (ORDER BY id ASC) FROM #source)
         UPDATE x
         SET x.source_id = src.id 
         FROM #xref AS x
            JOIN src ON src.ROW = x.ROW;
         GO

         -- Verify data
         SELECT * FROM #source;
         SELECT * FROM #target;
         SELECT * FROM #xref;
         GO

         -- Clean-up
         IF OBJECT_ID('TempDB..#source', 'U') IS NOT NULL DROP TABLE #source;
         IF OBJECT_ID('TempDB..#target', 'U') IS NOT NULL DROP TABLE #target;
         IF OBJECT_ID('TempDB..#xref', 'U') IS NOT NULL DROP TABLE #xref;
         GO