從表中檢索自動遞增的列值,其中在單個存儲過程中多次插入/選擇

[英]Retrieving auto-incremented column value from table where multiple insert/selects in single stored procedure


I have a stored procedure with multiple insert/select statements. Let's say I'm using the first insert to populate a "Manager" table. On insert, a ManagerId (incremented automatically) is added, but not referenced in the insert statement. I then wish to use the ManagerId from this table to insert a row into another table, where ManagerId is a foreign key. Sample code as follows..

我有一個包含多個insert / select語句的存儲過程。假設我正在使用第一個插入來填充“Manager”表。在插入時,添加了ManagerId(自動遞增),但未在insert語句中引用。然后,我希望使用此表中的ManagerId將行插入另一個表,其中ManagerId是外鍵。示例代碼如下..

USE [TEST]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[sptInsertNewManager]
    -- Add the parameters for the stored procedure here
    @FName varchar(50),
    @LName varchar(50),
    @EMail varchar(100),   
    @UserRoleID int,
    @LANUserID varchar(25), 
    @GroupID int
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
INSERT INTO [Manager]           
          ([FName], 
           [LName],
           [Email], 
           [UserRoleID],
           [LANUserID],          
           [ActiveFlag],
           [GroupID]
)
     VALUES
            (@FName
            ,@LName
            ,@EMail
            ,@UserRoleID
            ,@LANUserID
            ,1 
            ,@GroupID);

COMMIT

SELECT ManagerId FROM [Manager] AS newManager WHERE LANUserID = @LANUserID; 
        --also insert into Users table.
    INSERT INTO [dbo].[aspnet_Users] (
        [UserId],
        [UserName],
        [LoweredUserName],
        [ManagerId]
    )
        VALUES (
            NEWID(),
            @LANUserID,
            LOWER(@LANUserID),
            newManager)
END

This, obviously, does not work. This was my attempt at solving this. I'm fairly new to SQL, so any help with this problem would be greatly appreciated.

顯然,這不起作用。這是我試圖解決這個問題。我對SQL很新,所以對此問題的任何幫助都將非常感激。

6 个解决方案

#1


7  

use scope_identity() after your insert to capture the most recent single identity value from within your current scope:

在插入后使用scope_identity()從當前范圍內捕獲最新的單個標識值:

DECLARE @ID     int


INSERT ......
SELECT @ID=scope_identity()

use @ID wherever you need it

在任何需要的地方使用@ID

note: SCOPE_IDENTITY() is preferred over the older @@IDENTITY because it gives the last Identity value in the current scope, which avoids issues from triggers that insert into log tables (with identities).

注意:SCOPE_IDENTITY()優先於舊的@@ IDENTITY,因為它提供了當前范圍中的最后一個Identity值,這避免了插入日志表(帶有標識)的觸發器的問題。

However, if you need multiple identity values (inserting a set of rows), use OUTPUT and INTO:

但是,如果您需要多個標識值(插入一組行),請使用OUTPUT和INTO:

declare @test table (RowID  int identity(1,1) primary key not null, RowValue varchar(10) null)
declare @OutputTable table (RowID int not null)

insert into @test (RowValue)
    OUTPUT INSERTED.RowID
    INTO @OutputTable
    SELECT 'A'
    UNION SELECT 'B'
    UNION SELECT 'C'
    UNION SELECT 'D'
    UNION SELECT 'E'


select * from @OutputTable

the output:

輸出:

(5 row(s) affected)
RowID
-----------
1
2
3
4
5

(5 row(s) affected)

#2


2  

for MS Sql Server

對於MS Sql Server

Whenever you insert a record and it has auto-increment column (Identity Column in ms-sql parlance) you can user this to retrieve the id for the row you inserted:

無論何時插入記錄並且它具有自動增量列(ms-sql用語中的標識列),您都可以使用它來檢索您插入的行的ID:

@id = SCOPE_IDENTITY()

this ensures that you get the identity column value that your insert produced, not by the other users during the time your code was running (between insert and getting identity by scope_identity())

這可以確保您獲得插件生成的標識列值,而不是其他用戶在您的代碼運行期間(插入和通過scope_identity()獲取標識之間)

#3


2  

Yuck... you have your proc and transaction all twisted up...

哎呀......你的交易和交易都被扭曲了......

You want these two inserts to occur within the same transaction (which I am deducing from the COMMIT statement in the middle of your original proc). So you need to appropriately place a BEGIN TRANSACTION and COMMIT statement around all of your INSERT and SELECT statements to isolate the data change.

您希望這兩個插入在同一事務中發生(我從原始proc中間的COMMIT語句中推斷出)。因此,您需要在所有INSERT和SELECT語句周圍放置一個BEGIN TRANSACTION和COMMIT語句,以隔離數據更改。

Consider the following:

考慮以下:

CREATE PROCEDURE [dbo].[sptInsertNewManager]
    -- Add the parameters for the stored procedure here
    @FName varchar(50),
    @LName varchar(50),
    @EMail varchar(100),   
    @UserRoleID int,
    @LANUserID varchar(25), 
    @GroupID int
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

DECLARE @ManagerID  INT

BEGIN TRANSACTION    

    -- Insert statements for procedure here
INSERT INTO [Manager]           
          ([FName], 
           [LName],
           [Email],     
           [UserRoleID],
           [LANUserID],          
           [ActiveFlag],
           [GroupID]
)
     VALUES
                (@FName
                ,@LName
                ,@EMail
            ,@UserRoleID
            ,@LANUserID
                ,1 
            ,@GroupID);

-- Collect the ID you just created
SELECT @ManagerID = SCOPE_IDENTITY()


        --also insert into Users table.
    INSERT INTO [dbo].[aspnet_Users] (
        [UserId],
        [UserName],
        [LoweredUserName],
        [ManagerId]
    )
        VALUES (
                NEWID(),
                @LANUserID,
                LOWER(@LANUserID),
                @ManagerID)   -- This is the new identity you just created

COMMIT

END

#4


1  

ALso do not commit in the middle of the transaction, you want both inserts to rollback if one fails. Read in Books online about transaction processing.

也不要在事務中間提交,如果一個插入失敗,您希望兩個插入都回滾。在線閱讀有關交易處理的書籍。

#5


1  

We can return the identity column like:

我們可以返回標識列,如:

SELECT @@identity as 'Identity'

and read this identity value in code like:

並在代碼中讀取此標識值,如:

int ID = Convert.ToInt32(cmdinsert.ExecuteScalar());

#6


0  

You can use @@Identity global variable to retrieve last inserted identity value

您可以使用@@ Identity全局變量來檢索上次插入的標識值

SELECT @ManagerId=@@Identity

you can also use Scope_Identity and IDENT_Current functions

您還可以使用Scope_Identity和IDENT_Current函數


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2009/05/29/658ec75f7f33e94674997ead71cb3448.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com