将值插入多个SQL表

时间:2009-03-16 06:24:26

标签: c# sql sql-server

插入在C#和SQL server中的许多表上回复的表数据有什么好方法?

例如,我说我有以下表格:

Products: PK=PID, Product_Name
Build: PK:BID, Build_Number, FK:PID
Files: PK:FID, File_Name, FK:PID
FileDetails: PK:FDID, FK:FID, FK:BID, File_Size, File_Version

因此所有主键都是自动递增的数字

所以我有一个xml文件,在那里我有一些信息,例如:

Product_Name ,Build_Number,File_Name,File_Size,File_Version
FooCreator1.0,112233      ,foo.exe  ,123456   ,3.5
FooCreator1.0,112233      ,bar.exe  ,234567   ,1.5

我希望能够将行添加到我的表中。想象一下我的数据库是空的。

我首先要添加所有产品,然后添加所有构建,然后添加所有文件,然后加入所有表,然后添加所有文件详细信息?

编辑:我将有大约20,000行,我将在最终的唯一表中每行存储大约40个值。

5 个答案:

答案 0 :(得分:2)

这就是我要做的,虽然我不确定这是最好的方式:

declare @PID bigint
declare @BID bigint
declare @FID bigint

insert into Products (Product_Name)
values ('FooCreator1.0')

select @PID = scope_identity()

insert into Build (Build_Number, PID)
values (112233, @PID)

select @BID = scope_identity()

insert into Files (File_Name, PID)
values ('foo.exe', @PID)

select @FID = scope_identity()

insert into FileDetails (FID, BID, File_Size, File_Version)
values (@FID, @BID, 123456, '3.5')

那样的东西?可能想要在事务中运行整个事情,以防出现任何问题。

答案 1 :(得分:1)

基本上,是(last0。但是你怎么做可能取决于所涉及的行数。如果你有几百(可能是一千个左右),那么你可以使用一些东西像LINQ-to-SQL一样非常开心:创建你需要的对象,并使用InsertOnSubmit将必要的项添加到数据上下文中。最后,调用SubmitChanges(完成工作;其他ORM工具将工作同样)。

如果您有数万行(或其他),那么您可能只需将整个xml放入数据库(可能是带有xml参数的存储过程)。在数据库中使用Sql / xml,并从INSERT参数执行4 xml个语句。

对于数十万/数百万行,您需要使用SqlBulkCopy将数据推送到临时表(如您的示例所示) - 然后使用存储过程执行4 {{ 1}}秒。让xml像csv一样工作是bespoke data reader的工作。

答案 2 :(得分:0)

是。打开事务并按后续顺序添加行。您必须先添加产品并获取其ID才能添加Build并将该ID用作外键。您也可以将其写为存储过程。 SQL Server没有列表类型的过程参数,但如果您想在一个步骤中传递这样的复杂结构,并且您已经使用XML格式,那么您可以传递该文档,如SQL Server 2005(您没有t说你正在使用哪个版本)支持XML parameters。有了这个,您可以在存储过程中使用XPath来查询内容并构建数据。

答案 3 :(得分:0)

C#/。NET可能有更好的方法,但通常的做法是按照你的建议(大致)。对于XML文件中的每一行,您必须首先创建PRODUCT(如果已存在,则获取其PID)。

然后添加BUILD(如果它不存在)(如果是,则获取BID)。

然后添加FILE(如果它不存在)(如果是,则获取FID)。

然后在FILEDETAILS中添加或更新多对多关系。

每个插入/选择操作(产品,构建,文件)将如下所示:

insert into PRODUCTS (PRODUCT_NAME) VALUES ('FooCreator1.0')
// ignore errors from preceding statement
select PID from PRODUCTS where PRODUCT_NAME = 'FooCreator1.0'

因为,如果某人在创建该产品时击败了您,那么您只需要将其PID用于以后的插入。

答案 4 :(得分:0)

我建议使用Andy Whitestored procedure中提出的插入语句有以下几个原因:

  • 性能,允许DB编译和缓存语句。
  • 安全性,使用输入数据作为参数调用SP将限制恶意值的使用。
  • 将DB-stucture与客户端分开,如果/想要更改架构,则无需重新编译。
  • 可以在没有客户端干扰的情况下添加内部日志记录/错误处理。

Offcourse全部取决于操作的用法。如果它是一次性操作,则可能是矫枉过正。

您应该将语句封装在transaction中,以确保完成全部或全部操作,甚至使用TRY-CATCH。但正如我所写,这一切都取决于操作的用法。

/ JB