sql - 如何批量插入数据到两个SQL表

标签 sql database sql-server-2008

我的任务是读取一个大文件并将其中包含的数据插入到 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/

相关文章:

sql - 超过8000个字符时如何使用print语句

Mysql 左连接风格 sum()

mysql - 复杂的sql分组排序

sql - 试图理解 PLSQL 函数

sql-server-2008 - 如何在sql server 2008中仅显示偶数或奇数行?

SQL 将 float 转换为 varchar

SQL主键: integer vs varchar

python - 架构 - 能够在 Django 中更改电子邮件地址(主要用户 ID)

java - 如何从注册号牌中获取车主信息?

database - 城市国家数据库