我的任务是读取一个大文件并将其中包含的数据插入到 SQL 数据库中。在“真实”任务中,几个表中有 10 多个列,但为了便于讨论,我将使用更简单的模式。
数据如下: FName,LName,地址。
因此,我声明了一个 SQL 类型 BulkInsertData
来保存这三个字段,以便它们可以作为表值参数传入。
这是我的表格:
dbo.Person
---+-------+-------+----------+
Id | Fname | Lname | AddressId|
---+-------+-------+----------+
1 | Bob | Smith | 42 |
2 | Sue | Baker | 234 |
---+-------+-------+----------+
dbo.Address
----+----------------------+
Id | Address |
----+----------------------+
42 | 1600 Pennsylvania Ave|
234 | 10 Downing St |
----+----------------------+
我的目标是将名字和姓氏插入到 dbo.Person 表中,将地址插入到 dbo.Address 表中,以及适当的外键。将数据插入多个表很容易,但我卡在外键关系上。
如果我只插入一条记录,我可能会将地址插入到 dbo.Address 表中,然后使用 SELECT @@IDENTITY
获取要插入的新地址的 ID dbo.Person 以及名字和姓氏。
在这里,Does SQL Server have something like @@IDENTITY that returns multiple values? ,另一位 Stacker 向我解释说,INSERT 语句与 OUTPUT 语句一起使用,以保存有关多个插入行的信息。
我想我想做的是有一个临时表,它不仅可以保存传入的数据,还可以保存与每个人关联的主键和外键:一个可以保存 Fname、Lname、地址、PersonId 和 AddressId。
但是,据我所知,我可以使用 OUTPUT 关键字在临时表中创建新行,但我不知道如何使用它来修改现有行。
我感觉这个任务应该不难,那我该怎么做呢?
我的 SQL 服务器是 MS SQL Server 2008。
如果我拿下面的数据...
Adam, Dumas, 300 Broadway
Greg, Ho, 213 Main St
并将其批量插入到我上面描述的表中,结果应该如下所示:
dbo.Person
---+-------+-------+----------+
Id | Fname | Lname | AddressId|
---+-------+-------+----------+
1 | Bob | Smith | 42 |
2 | Sue | Baker | 234 |
3 | Adam | Dumas | 501 |
4 | Greg | Ho | 502 |
---+-------+-------+----------+
dbo.Address
----+----------------------+
Id | Address |
----+----------------------+
42 | 1600 Pennsylvania Ave|
234 | 10 Downing St |
501 | 300 Broadway |
502 | 213 Main St |
----+----------------------+
最佳答案
CREATE TABLE TVP_ADDRESS
(
ID INT IDENTITY(1,1) PRIMARY KEY,ADDRESS VARCHAR(100)
)
CREATE TABLE TVP_PERSON
(
ID INT IDENTITY(1,1) PRIMARY KEY,FNAME VARCHAR(100),LNAME VARCHAR(100),ADDRESS_ID INT,CONSTRAINT fk_address_id_tvp_address FOREIGN KEY(address_id) REFERENCES tvp_address(id) ON DELETE CASCADE
)
CREATE TYPE TVPDATA
AS
TABLE
(
FNAME VARCHAR(100),LNAME VARCHAR(100),ADDRESS VARCHAR(100)
)
GO
CREATE PROCEDURE inser_tvpdata
(
@TVP TVPDATA READONLY
)
AS
BEGIN
DECLARE @T TABLE(ID INT,ADDRESS VARCHAR(100))
--first insert address get ids
INSERT INTO TVP_ADDRESS(address) OUTPUT Inserted.* INTO @T
SELECT DISTINCT
t.address
FROM @TVP t --LEFT OUTER JOIN TVP_address td ON t.address = td.address
--WHERE td.address IS NULL
-- insert persons and get new ids
INSERT INTO tvp_person(Fname,lname,address_id)
SELECT t.fname,t.lname,temp.id
FROM @TVP t
INNER JOIN @T temp ON temp.ADDRESS=t.address
END
GO
DECLARE @t TVPDATA
INSERT INTO @t(fname,lname,address) VALUES ('john','r','test'),('steve','r','test2')
EXEC inser_tvpdata @t
SELECT *
FROM TVP_ADDRESS
SELECT *
FROM TVP_PERSON
关于sql - 如何批量插入数据到两个SQL表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28416045/