Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用UDT插入数据?_C#_Asp.net_Sql Server_Stored Procedures_User Defined Types - Fatal编程技术网

C# 如何使用UDT插入数据?

C# 如何使用UDT插入数据?,c#,asp.net,sql-server,stored-procedures,user-defined-types,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 -------------

我对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!=''
据我所知,块1只是声明临时表/变量的结构。 在块2中,用户传递存储在临时表/变量中的输入数据

我很难理解块3块4

我不明白在插入查询之前更新查询在做什么

第三区和第四区的目的是什么


(代码运行正常,没有错误。)

[1]关于此源代码,我想注意的第一件事不是使用另一个表变量(
@TP
),而是缺少事务管理,也缺少错误处理。至少有两条语句(最后两条:UPDATE和INSERT)存在在语句级生成异常/错误的风险(例如)

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

[3] 注:两个表变量(
@TP
@Supplier\u UDT
)具有相同的列或(至少)一组公共列:
ID、Suppliercode、Suppliername、GSTVATNumber、Description、Productlist、Bankdetails、pymenttermsdescription、Currency、Pendingpayement、pendingorders、Active
。不清楚数据类型、NULL能力和约束是否相同

[4] 块3和块4似乎是模式的实现,但对于许多行(注意:UPSERT的大多数示例仅使用一行)。这意味着对于那些已经存在于
dbo.Supplier
表中的供应商(SQL模式应该是强制性的)
UPDATE
语句将使用最新值更改/更新以下列
SupplierCode,SupplierName,
,新供应商将
插入
dbo.Supplier
表中

正如Dan Guzman在其评论(+1)中已经提到的,可以使用一个
MERGE
语句代替这两个语句(
UPDATE
INSERT
):

 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
table hint?请参阅丹·古兹曼的博客:

[6] 此外,此处描述的MERGE语句也存在一些错误:

其中有些或多或少是严重的


[7]

我们无法知道贵公司业务逻辑的原因。这也是离题的,因为Soblock 1/2似乎是多余的,因为
@TP
可以用
@Supplier\u UDT
替换。如果
@TP
具有上一个供应商ID中没有的ID,则块3使用
@TP
中的值更新供应商表insert将它们添加为新行。不需要表变量来保存表值参数的内容。您可以像使用表一样使用参数。可以使用单个
MERGE
语句执行
insert
UPDATE
。通过消除loca,proc可以是单个语句l表变量。只需使用块3和块4中的现有代码。但不要使用@TP表参数。哇,这是一个惊人的指导。非常感谢。感谢您的过程,我将参考创建新过程:)