我正在编写一个SQL脚本来为我们的数据库生成测试数据。我正在表变量中生成数据(所以我可以稍后跟踪它),然后将其插入到真实的表中。问题是,我需要跟踪我添加到父表中的哪些行,以便稍后我可以在脚本中生成其子数据。例如:
CREATE TABLE Customer (
CustomerId INT IDENTITY,
Name VARCHAR(50)
)
CREATE TABLE Order (
OrderId INT IDENTITY,
CustomerId INT,
Product VARCHAR(50)
)
因此,在我的脚本中,我创建了等效的表变量:
DECLARE @Customer TABLE (
CustomerId INT IDENTITY,
Name VARCHAR(50)
) -- populate customers
DECLARE @Order TABLE (
OrderId INT IDENTITY,
CustomerId INT,
Product VARCHAR(50)
) -- populate orders
我生成并将样本数据插入到每个表变量中。
现在,当我将来自我的表变量的客户插入到真实表中时,表变量中的CustomerId
列将变得毫无意义,因为真实表具有其{{1}的自己的标识种子}专栏。
有没有办法可以跟踪插入到真实表中的每一行的新标识,在我的表变量中,所以我可以使用适当的CustomerId
作为订单记录?或者,我有更好的方法来解决这个问题吗?
(注意:我最初使用的应用程序来生成测试数据,但在插入过程中运行得太慢,因为需要生成> 1,000,000条记录。)
答案 0 :(得分:2)
您为什么需要表变量的标识值?如果只使用int,则在插入完成后可以使用is。使用output子句抓取它们。你可能需要一个输入值和一个输出值表来变量,这样就可以了:
DECLARE @CustomerInputs TABLE (Name VARCHAR(50) )
DECLARE @CustomerOutputs TABLE (CustomerId INT ,Name VARCHAR(50) )
INSERT INTO CUSTOMERS (name)
OUTPUT inserted.Customerid, inserted.Name INTO @CustomerOutputs
SELECT Name FROM @CustomerInputs
SELECT * from @CustomerOutputs
答案 1 :(得分:0)
您可以使用游标将数据插入表中,并使用内置函数SCOPE_IDENTITY()
获取当前作用域中插入的最后一个ID(通过脚本)。
有关SCOPE_IDENTITY
的详细信息,请参阅this MSDN article。
答案 2 :(得分:0)
这是一种做法。如果你可以使用它取决于你的情况。当用户使用您的数据库时,您不应该在生产环境中执行此操作。
-- Get the next identity values for Customer and Order
declare @NextCustomerID int
declare @NextOrderID int
set @NextCustomerID = IDENT_CURRENT('Customer')+1
set @NextOrderID = IDENT_CURRENT('Order')+1
-- Create tmp tables
create table #Customer (CustomerID int identity, Name varchar(50))
create table #Order (OrderID int identity, CustomerID int, Product varchar(50))
-- Reseed the identity columns in temp tables
dbcc checkident(#Customer, reseed, @NextCustomerID)
dbcc checkident(#Order, reseed, @NextOrderID)
-- Populate #Customer
-- Populate #Order
-- Allow insert to identity column on Customer
set identity_insert Customer on
-- Add rows to Customer
insert into Customer(CustomerId, Name)
select CustomerID, Name
from #Customer
-- Restore identity functionality on Customer
set identity_insert Customer off
-- Add rows to Order
set identity_insert [Order] on
insert into [Order](OrderID, CustomerID, Product)
select OrderID, CustomerID, Product
from #Order
set identity_insert [Order] off
-- Drop temp tables
drop table #Customer
drop table #Order
-- Check result
select * from [Order]
select * from Customer
答案 3 :(得分:-1)
我这样做的方式是首先从您的客户表中获取MAX(CustomerId)
。然后我将摆脱变量表上的IDENTITY
列,并使用ROW_NUMBER()
和MaxCustomerId执行我自己的CustomerId。它应该是这样的:
DECLARE @MaxCustomerId INT
SELECT @MaxCustomerId = ISNULL(MAX(CustomerId),0)
FROM Customer
DECLARE @Customer TABLE (
CustomerId INT,
Name VARCHAR(50)
)
INSERT INTO @Customer(CustomerId, Name)
SELECT @MaxCustomerId + ROW_NUMBER() OVER(ORDER BY SomeColumn), Name
FROM YourDataTable
或者在临时表中插入值,这样您就可以使用相同的ID来填充Order表。