繁体   English   中英

SQL Server存储过程 - 检查是否存在任何记录,如果不存在则插入

[英]SQL Server stored procedure - check if ANY records exist, and insert if not

题:

是否可以使用指定的一段时间向SQL Server 2012发送单个调用,以便数据库服务器可以检查是否存在任何这些元素,如果不存在,则将它们插入表中?

问题:

我面临的问题是,我有一个预定的作业(调用API),每次调用它都会返回大约400条记录。 这个工作每分钟调用一次,最慢的是,对于每个结果,我正在检查数据库是否已经有记录,如果没有,那么我正在进行INSERT。

示例:API返回400人。 我希望能够在一次调用数据库时发送每个人的ID以及姓名等。 然后,DB应该检查并查看ID是否存在(对于每个Person),如果不存在,则执行INSERT。

反馈:

我还想了解这是否是一个好的做法,或者是否有更好的方法来处理这个问题。

根据我的理解,作业将结果返回给应用程序(C#),然后此应用程序为每个记录调用DB。

答案是肯定的,你可以在一个补丁中向sql server发送多个记录(datatable),然后sql server将处理所有这些数据。

首先在SQL Server中,您必须定义将从应用程序发送到DB的格式的表数据类型。

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>);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM