过程如何使用UDT插入数据?

时间:2017-06-30 13:58:15

标签: c# asp.net sql-server stored-procedures user-defined-types

我是ASP.net的新手,也是UDT的概念。我曾经在PHP上工作,因此我很难理解UDT概念。

这是为将数据从输入表单插入数据库(SQL Server)而编写的存储过程。

代码工作正常,由我公司的高级开发人员编写。

    CREATE Procedure [dbo].[Save_Supplier]
    @Supplier_UDT Supplier_UDT Readonly,
    @UserName varchar(80)
    AS
    Begin

    -------------Block 1------
    Declare @TP Table(ID int,Suppliercode varchar(80),Suppliername varchar(80),GSTVATNumber int,Description varchar(80),Productlist varchar(80),Bankdetails varchar(80),
    pymenttermdescription varchar(80),Currency int,Pendingpayement Varchar(80),pendingorders int,Active bit )

 -------------Block 2------
    Insert into @TP(ID ,Suppliercode ,Suppliername,GSTVATNumber,Description ,Productlist,Bankdetails,pymenttermdescription,Currency,Pendingpayement ,pendingorders ,Active)
    select ID ,Suppliercode ,Suppliername,GSTVATNumber,Description ,Productlist,Bankdetails,pymenttermdescription,Currency,Pendingpayement ,pendingorders ,Active from @Supplier_UDT

 -------------Block 3------
    Update Supplier
    set 
    Suppliercode=a.Suppliercode ,
    Suppliername=a.Suppliername
    ,GSTVATNumber=a.GSTVATNumber
    ,Description =a.Description
    ,Productlist=a.Productlist
    ,Bankdetails=a.Bankdetails
    ,pymenttermdescription=a.pymenttermdescription
    ,Currency=a.Currency
    ,Pendingpayement=a.Pendingpayement
     ,pendingorders=a.pendingorders 
     ,Active=a.Active
     from @TP a inner join Supplier
     on a.ID=Supplier.ID

 -------------Block 4------
     Insert into Supplier(Suppliercode ,Suppliername,GSTVATNumber,Description ,Productlist,Bankdetails,pymenttermdescription,Currency,Pendingpayement ,pendingorders ,Active)
     select Suppliercode ,Suppliername,GSTVATNumber,Description ,Productlist,Bankdetails,pymenttermdescription,Currency,Pendingpayement ,pendingorders ,Active
     from @TP where ID not in (select ID from Supplier) and Suppliercode!=''

据我了解,Block 1只是声明临时表/变量的结构。 在块2中,用户传递存储在临时表/变量中的输入数据。

我很难理解 Block 3 Block 4

我不明白在INSERT查询之前UPDATE查询是做什么的?

Block 3和Block 4的目的是什么?

(代码工作正常,没有错误。)

1 个答案:

答案 0 :(得分:1)

[1]我首先要注意的是这个源代码不是使用另一个表变量(@TP)而是缺少事务管理而且错过了错误处理。至少有两个语句(最后两个:UPDATE和INSERT)存在在语句级别生成异常/错误的风险(例如)。

[2]我没有看到任何理由再使用一个表变量(@TP),第一个是参数@Supplier_UDT Supplier_UDT。它将创建/增加tempdb contention,并且从开发人员的角度来看将创建另一个依赖项(例如:如果我们要在dbo.Supplier表中更改其中一列的数据类型,那么我们&# 39;还必须更新此@TP列的存储过程和定义。

[3]注意:两个表变量(@TP@Supplier_UDT)具有相同的列或(至少)一组公共列:ID ,Suppliercode ,Suppliername,GSTVATNumber,Description ,Productlist,Bankdetails,pymenttermdescription,Currency,Pendingpayement ,pendingorders ,Active。如果数据类型,NULL能力和约束相同,则不清楚。

[4] Block 3&amp; 4似乎是UPSERT 模式的实现,但对于许多行(注意:UPSERT的大多数示例仅使用一行)。这意味着对于那些已经存在于dbo.Supplier表中的供应商(SQL模式应该是必需的)UPDATE语句将更改/更新列SupplierCode, SupplierName, ...之后的<{1}} em>最新值和新供应商INSERT已加入dbo.Supplier表。

正如Dan Guzman在他的评论(+1)中已经提到的那样,可以使用单个UPDATE语句而不是这两个语句(INSERTMERGE):

 MERGE dbo.Supplier WITH(HOLDLOCK) AS dst  -- Destination table
 USING @Supplier_UDT AS src ON dst.ID = src.ID -- Source table
 WHEN MATCHED THEN 
    UPDATE
    SET 
    Suppliercode    = a.Suppliercode ,
    Suppliername    = a.Suppliername,
    GSTVATNumber    = a.GSTVATNumber,
    Description     = a.Description,
    Productlist     = a.Productlist,
    Bankdetails     = a.Bankdetails,
    pymenttermdescription = a.pymenttermdescription,
    Currency        = a.Currency,
    Pendingpayement = a.Pendingpayement,
    pendingorders   = a.pendingorders,
    Active          = a.Active
WHEN NOT MATCHED AND dst.Suppliercode != '' THEN -- Please make sure that Suppliercode refers to destination table and not to source table 
    INSERT (Suppliercode ,Suppliername,GSTVATNumber,Description ,Productlist,Bankdetails,pymenttermdescription,Currency,Pendingpayement ,pendingorders ,Active)
    VALUES (Suppliercode ,Suppliername,GSTVATNumber,Description ,Productlist,Bankdetails,pymenttermdescription,Currency,Pendingpayement ,pendingorders ,Active);

[5]为什么我会使用HOLDLOCK表提示?请参阅Dan Guzman的博客:http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx

[6]另外,这里描述的MERGE语句有一些错误: https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/

其中一些或多或少严重

[7] If it ain't broke, don't fix it