SQL Server存储过程 - 检查是否有任何记录存在,然后插入如果不是
问:SQL Server存储过程 - 检查是否有任何记录存在,然后插入如果不是
是否可以发送到SQL Server 2012的单呼,用一段时间指定了一个数组,使数据库服务器可以检查这些元素是否存在,如果不存在,将它们插入表中?
问题:
我面临的问题是,我有一个计划作业(调用API),返回大约400每次调用时间记录。这项工作每分钟都会被调用,而最慢的是,对于每个结果,我正在检查数据库是否已经有记录,如果没有,那么我正在执行INSERT。
示例:API返回400人。我希望能够在一次调用中将每个人的ID以及姓名等发送给数据库。然后数据库应该检查并查看ID是否存在(对于每个人),如果不存在,则执行INSERT。
反馈:
我也想在此是否真的是很好的做法的建议,或有处理这更好的方式。
按我的理解,这项工作的结果返回给应用程序(C#),那么这个应用程序在调用数据库的每个记录。
答案是肯定的,你可以在一个补丁中发送多个记录(数据表)到sql服务器,然后sql服务器将处理所有这些数据。
首先在SQL Server中,您必须定义将从应用程序发送到数据库的格式的表格数据类型。
CREATE TYPE YourDataType AS TABLE(
[Col1] [int] NULL, [Col2] [int] NULL, [Col3] [int] NULL, [Col4] [nvarchar](255) NULL,
[Col5] [nvarchar](255) NULL, [Col6] [nvarchar](255) NULL, [Col7] [nvarchar](255) NULL, [Col8] [nvarchar](255) NULL,
[Col9] [nvarchar](255) NULL, [Col10] [nvarchar](255) NULL, [Col11] [int] NULL, [Col12] [nvarchar](255) NULL,
)
GO
然后创建将使用此数据类型
CREATE PROCEDURE YourProcedureName (@TableVariable YourDataType READONLY, @ScalarParameter nvarchar(255))
AS
BEGIN
INSERT INTO YourTable WITH (ROWLOCK) (Col1,Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12)
SELECT Col1,Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12
FROM @TableVariable t
/*Left Join then where ID is null to make sure the record doesn't exists*/
LEFT JOIN YourTable PR WITH (NOLOCK)
ON PR.ID = @ScalarParameter
AND PR.Col1 = t.Col1
AND PR.Col2 = t.Col2
......
WHERE PR.ID IS NULL
END
最后使用您的数据应用程序中调用这个程序你的程序。 在这里,我写的使用VB.Net,但你可以在C#重写一遍:
Dim connectionString As StringBuilder = New StringBuilder()
connectionString.AppendFormat("Server={0};", ????)
connectionString.AppendFormat("Database={0};", ???)
connectionString.AppendFormat("User ID={0};", ????)
connectionString.AppendFormat("Password={0}", ????)
Dim InputTable As DataTable = New DataTable("YourDataType")
InputTable = ds.Tables(0).Copy()
InputTable.TableName = "YourDataType"
Try
Using conn As New SqlClient.SqlConnection(connectionString.ToString())
Using comm As New SqlClient.SqlCommand()
Dim insertedRecords As Int32
comm.Connection = conn
comm.CommandText = "YourProcedureName"
comm.CommandType = CommandType.StoredProcedure
Dim TableVariable As SqlClient.SqlParameter = comm.Parameters.Add("@TableVariable", SqlDbType.Structured)
TableVariable.Direction = ParameterDirection.Input
TableVariable.Value = InputTable
Dim ScalarVariable As SqlClient.SqlParameter = comm.Parameters.Add(@ScalarParameter, SqlDbType.VarChar)
ScalarVariable.Direction = ParameterDirection.Input
ScalarVariable.Value = ???
conn.Open()
insertedRecords = comm.ExecuteNonQuery()
If (insertedRecords > 0) Then
_Changed = True
End If
conn.Close()
comm.Dispose()
conn.Dispose()
End Using
End Using
Catch ex As Exception
Return False
End Try
Return True
您需要一种方法来确定记录是否已在表格中。这需要进行某种比较。
一旦你有,你可以构造这样的查询:
insert into t(. . .)
select v.*
from values ((v1), (v2), . . .) as v(vcol)
where not exists (select 1 from v where v.vcol = t.<whatever>);
可能合并会更富有表现力,如果存在则使用密钥 MERGE INTO test AS trg USING(VALUES(@ v1), (@ v3))AS src(Newt) ON trg.t = src.Newt WHEN NOT MATCHED THEN INSERT(t)VALUES(NewT);' – vitalygolub
@vitalygolub。 。 。这可能是我,但我几乎从未发现“合并”更容易阅读。 –
有没有可能是许多这样的调用会同时击中分贝?如果没有,那么你应该将它们加载到暂存表中并运行某种“MERGE”。如果你将有多个调用(意味着你不能使用单个表,因为它们会覆盖对方),那么请看“将数组传递给存储过程” - http://stackoverflow.com/questions/11102358/how-to -pass-an-array-into-a-sql-server-stored-procedure –