我刚刚遇到一种情况,我必须在数据库中插入多个记录。我的记录在通用列表中,现在我发现了两种插入多个记录的方法。
我只是像往常一样使用ExecuteNonQuery来执行此操作,并且我使用foreach循环逐个插入每条记录(我不认为这是最好的方法,因为这种方法会多次访问数据库插入记录)。
using (SqlCommand cmd = new SqlCommand()
{
using (SqlConnection conn = new SqlConnection()
{
cmd.Connection = conn;
foreach (var entry in entries)
{
cmd.CommandText = "INSERT INTO Employees(id, name) VALUES
(@id,@name);";
cmd.Parameters.AddWithValue("@id", entry.Id);
cmd.Parameters.AddWithValue("@name", entry.Name);
cmd.ExecuteNonQuery();
}
}
}
我尝试使用SqlBulkCopy类,将通用列表转换为DataTable并使用了SqlBulkCopy。
using (SqlConnection con = new SqlConnection(consString))
{
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(con))
{
sqlBulkCopy.DestinationTableName = "Employees";
con.Open();
sqlBulkCopy.WriteToServer(dt);
con.Close();
}
}
这两种方法都能完成预期的工作。但是我想知道哪种是最好的方法。如果还有其他更好的方法可以这样做,我可以提出建议。
答案 0 :(得分:2)
使用在SQL Server 2008中引入的表值参数(TVP)。在SQL Server 2008之前,不可能在存储过程中将表变量作为参数传递,在SQL Server之后,我们现在可以传递Table-值参数,用于将多行数据发送到存储过程或函数,而无需创建临时表或传递太多参数。看下面的例子
CREATE TYPE UT_Employee AS TABLE
(
Emp_Id int NOT NULL,
EmployeeName nvarchar(MAX),
EmpSalary varchar(50),
StateId varchar(50),
CityId varchar(50)
)
CREATE PROCEDURE USP_Insert_Employee_Info
(
@Employee_Details [UT_Employee] READONLY
)
AS
BEGIN
INSERT INTO dbo.Employee
(
Emp_Id,
EmployeeName,
EmpSalary,
StateId,
CityId
)
SELECT * FROM @Employee_Details
END
按如下所示将多个值插入存储过程
DECLARE @Employee_Details AS UT_Employee
INSERT INTO @Employee_Details
SELECT 1001,'Abcd',10000,101,21 UNION ALL
SELECT 1002,'dggg',20000,121,15 UNION ALL
SELECT 1003,'esse',22222,122,35 UNION ALL
SELECT 1004,'uyyy',44333,121,32 UNION ALL
SELECT 1005,'dghd',13233,656,87
EXEC dbo.USP_Insert_Employee_Info @Employee_Details = @Employee_Details
答案 1 :(得分:2)
我通常为此使用表值参数。有关如何执行此操作的说明在此处稍长,但请查看Microsoft文档上的Table-Valued Parameters以了解如何执行此操作。