将新记录插入自动编号 table,然后在另一个 table 中使用自动编号
Insert new record into autonumbered table, and then use the autonumber in another table
我正在编写一个存储过程以将表单中的数据插入到两个 table 中。一个 table 有一个自动编号的身份字段。我需要将数据插入 table,找到新创建的自动编号,然后使用该编号将数据插入另一个 table。所以,归结起来,我在两个 table 之间有一个一对多的 link,我需要确保插入身份字段。
这段代码是执行此类操作的最佳方法吗,还是我遗漏了一些明显的东西?
CREATE PROCEDURE [dbo].[sp_Insert_CRT]
(
@TRACKING_ID int,
@CUST_NUM int,
@TRACKING_ITEM_ID int,
@STATEMENT_NUM nvarchar (200) = null,
@AMOUNT numeric (15, 2),
@BBL_ADJUSTED int = NULL,
@PAID_VS_BILLED int = NULL,
@ADJUSTMENT_TYPE int = NULL,
@ENTERED_BY nvarchar (10) = NULL,
@ENTERED_DATE date = NULL,
@AA_STATUS int = NULL
)
AS
BEGIN
-- Insert data into CRT_Main, where Tracking_ID is an autonumber field
INSERT into tbl_CRT_Main
(
-- TRACKING_ID
CUST_NUM
,TRACKING_ITEM_ID
,STATEMENT_NUM
,AMOUNT
)
VALUES
(
-- @TRACKING_ID
@CUST_NUM
,@TRACKING_ITEM_ID
,@STATEMENT_NUM
,@AMOUNT
)
-- Find the newly generated autonumber, and use it in another table
BEGIN TRANSACTION
DECLARE @TrackID int;
SELECT @TrackID = coalesce((select max(TRACKING_ID) from tbl_CRT_Main), 1)
COMMIT
INSERT into tbl_CRT_Admin_Adjustment
(
TRACKING_ID
,BBL_ADJUSTED
,PAID_VS_BILLED
,[ADJUSTMENT_TYPE]
,[ENTERED_BY]
,[ENTERED_DATE]
,AA_STATUS
)
VALUES
(
@TrackID
,@BBL_ADJUSTED
,@PAID_VS_BILLED
,@ADJUSTMENT_TYPE
,@ENTERED_BY
,@ENTERED_DATE
,@AA_STATUS
)
END
SELECT @TrackID = coalesce((select max(TRACKING_ID) from tbl_CRT_Main), 1)
不,不要这样做。这将使您获得 TRACKING_ID
的最大值,是的,但这并不意味着那是为您的 INSERT
创建的值。如果多个 INSERT
语句被不同的连接 运行 那么你很可能会得到 错误的 值。
相反,使用 SCOPE_IDENTITY
获取值:
SET @TrackID = SCOPE_IDENTITY();
此外,无需像 SELECT MAX()
那样将上述内容包装在显式交易中。相反,最有可能的是,过程中的 entire batch 应该在它自己的显式事务中,带有 TRY...CATCH
这样你就可以 ROLLBACK
中的整个 batch错误事件。
我正在编写一个存储过程以将表单中的数据插入到两个 table 中。一个 table 有一个自动编号的身份字段。我需要将数据插入 table,找到新创建的自动编号,然后使用该编号将数据插入另一个 table。所以,归结起来,我在两个 table 之间有一个一对多的 link,我需要确保插入身份字段。
这段代码是执行此类操作的最佳方法吗,还是我遗漏了一些明显的东西?
CREATE PROCEDURE [dbo].[sp_Insert_CRT]
(
@TRACKING_ID int,
@CUST_NUM int,
@TRACKING_ITEM_ID int,
@STATEMENT_NUM nvarchar (200) = null,
@AMOUNT numeric (15, 2),
@BBL_ADJUSTED int = NULL,
@PAID_VS_BILLED int = NULL,
@ADJUSTMENT_TYPE int = NULL,
@ENTERED_BY nvarchar (10) = NULL,
@ENTERED_DATE date = NULL,
@AA_STATUS int = NULL
)
AS
BEGIN
-- Insert data into CRT_Main, where Tracking_ID is an autonumber field
INSERT into tbl_CRT_Main
(
-- TRACKING_ID
CUST_NUM
,TRACKING_ITEM_ID
,STATEMENT_NUM
,AMOUNT
)
VALUES
(
-- @TRACKING_ID
@CUST_NUM
,@TRACKING_ITEM_ID
,@STATEMENT_NUM
,@AMOUNT
)
-- Find the newly generated autonumber, and use it in another table
BEGIN TRANSACTION
DECLARE @TrackID int;
SELECT @TrackID = coalesce((select max(TRACKING_ID) from tbl_CRT_Main), 1)
COMMIT
INSERT into tbl_CRT_Admin_Adjustment
(
TRACKING_ID
,BBL_ADJUSTED
,PAID_VS_BILLED
,[ADJUSTMENT_TYPE]
,[ENTERED_BY]
,[ENTERED_DATE]
,AA_STATUS
)
VALUES
(
@TrackID
,@BBL_ADJUSTED
,@PAID_VS_BILLED
,@ADJUSTMENT_TYPE
,@ENTERED_BY
,@ENTERED_DATE
,@AA_STATUS
)
END
SELECT @TrackID = coalesce((select max(TRACKING_ID) from tbl_CRT_Main), 1)
不,不要这样做。这将使您获得 TRACKING_ID
的最大值,是的,但这并不意味着那是为您的 INSERT
创建的值。如果多个 INSERT
语句被不同的连接 运行 那么你很可能会得到 错误的 值。
相反,使用 SCOPE_IDENTITY
获取值:
SET @TrackID = SCOPE_IDENTITY();
此外,无需像 SELECT MAX()
那样将上述内容包装在显式交易中。相反,最有可能的是,过程中的 entire batch 应该在它自己的显式事务中,带有 TRY...CATCH
这样你就可以 ROLLBACK
中的整个 batch错误事件。