【问题标题】:Adding a collection of User-Defined Table Types in a stored procedure to SQL Server将存储过程中的用户定义表类型集合添加到 SQL Server
【发布时间】:2017-04-02 18:56:27
【问题描述】:

我想知道是否有人可以帮助我或指出正确的方向,因为我试图弄清楚是否可以将用户定义表类型的集合放入另一个我正在尝试批量插入父表和子表的集合到 SQL Server 数据库中。我可以单独执行此操作,但我想知道这是否可以一次完成 100 个订单,而不是在一个循环中发送许多插入并且必须将列表订单拆分为单独的订单,然后将订单和订单详细信息拆分为两个单独的数据表。

我似乎无法弄清楚如何调整以下内容,以发送一组订单而不是一次发送一个。无需拆分它们,还可以确保它仍将正确的子行插入到正确的父记录中。因为一个订单可以有无限数量的行详细行。

用户定义的表类型

CREATE TYPE dbo.ordertype
AS TABLE
(
    orderdate datetime,
    ordernumber varchar(50) not null,
    totalprice       decimal(18,0) not null,
);

CREATE TYPE dbo.orderdetailtype
AS TABLE
(
    productname varchar(50) not null,
    price       decimal(18,0) not null,
    qty         int not null
);

存储过程:

CREATE PROCEDURE [dbo].[sp_tes]
                 @ordertype          ordertype       ReadONLY,
                 @orderdetailtype    orderdetailtype ReadONLY

AS
BEGIN

   SET NOCOUNT ON

    DECLARE @orderid INT 

    INSERT INTO dbo.orders (orderdate, ordernumber, totalprice  )
    SELECT orderdate, ordernumber, totalprice                                     
    FROM @ordertype;

    SET @orderid = SCOPE_IDENTITY()
    SELECT @orderid

    INSERT INTO dbo.orderdetails( productname, price, qty )
    SELECT productname, price, qty
    FROM @orderdetailtype;

    return @orderid

END

使用c#调用

        using (SqlCommand cmd = con.CreateCommand())
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "sp_tes";

            cmd.Parameters.Add("@ordertype", SqlDbType.Structured).Value = order;
            cmd.Parameters.Add("@orderdetailtype", SqlDbType.Structured).Value = orderdetails;
            SqlParameter returnParameter = cmd.Parameters.Add("@Returns", SqlDbType.Int);
            returnParameter.Direction = ParameterDirection.ReturnValue;
            cmd.ExecuteNonQuery();
        }

【问题讨论】:

  • 您可以将ordernumber 列添加到您的orderdetailtype 表类型吗?如果是这样,您可以循环遍历ordertype,并且每次从orderdetailtype 插入ordernumber 匹配。现在,您的 orders 和 orderdetails 表之间没有明显的关系。
  • 感谢您的回复。是的,如果必须,我可以,您能否提供一个循环示例并从中插入。
  • 查看我对similar question.的回答

标签: c# sql sql-server stored-procedures datatable


【解决方案1】:

这两种表类型都需要一个连接字段。可能是订单号?使用OUTPUT 子句返回表变量中的新id,并将其连接到第二个参数表中。

CREATE TYPE dbo.ordertype
AS TABLE
(
    orderdate   datetime,
    ordernumber varchar(50)    not null,
    totalprice  decimal(18, 2) not null
)

CREATE TYPE dbo.orderdetailtype
AS TABLE
(
    orderNumber varchar(50)    not null,
    productname varchar(50)    not null,
    price       decimal(18, 2) not null,
    qty         int            not null
)

CREATE TABLE dbo.orders
(
    orderid     INT IDENTITY(1, 1)  not null, 
    orderdate   datetime,
    ordernumber varchar(50)    not null,
    totalprice  decimal(18, 2) not null
)

CREATE TABLE dbo.orderdetails
(
    orderid     INT            not null, 
    productname varchar(50)    not null,
    price       decimal(18, 2) not null,
    qty         int            not null
)

GO

CREATE PROCEDURE [dbo].[sp_tes]
  @ordertype       dbo.ordertype       READONLY,
  @orderdetailtype dbo.orderdetailtype READONLY
AS
BEGIN
  SET NOCOUNT ON

  DECLARE
    @newIds AS TABLE (
      ordernumber VARCHAR(50),
      orderId     INT
    )

  INSERT
    INTO dbo.orders (orderdate, ordernumber, totalprice)
  OUTPUT inserted.ordernumber, inserted.orderid INTO @newIds
         SELECT orderdate, ordernumber, totalprice                                     
           FROM @ordertype

  INSERT 
    INTO dbo.orderdetails(orderId, productname, price, qty)
         SELECT T1.orderId, T2.productname, T2.price, T2.qty
           FROM @newIds T1
                INNER JOIN @orderdetailtype T2
                        ON T1.orderNumber = T2.orderNumber

  SELECT *
    FROM @newIds
END

GO

DECLARE
  @ordertype       dbo.ordertype,
  @orderdetailtype dbo.orderdetailtype

INSERT 
  INTO @ordertype
       SELECT GETDATE(), '2016/0001', 22.48
       UNION
       SELECT GETDATE(), '2016/0002', 19.98
INSERT 
  INTO @orderdetailtype
       SELECT '2016/0001', 'Sql Guide',  9.99, 1
       UNION
       SELECT '2016/0001', 'Introducing Microsoft SQL Server 2016', 12.49, 1
       UNION
       SELECT '2016/0002', 'Sql Guide',  9.99, 2

EXEC [dbo].[sp_tes] @ordertype, @orderdetailtype

SELECT *
  FROM dbo.orders
SELECT *
  FROM dbo.orderdetails

【讨论】:

    猜你喜欢
    • 2021-11-04
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    相关资源
    最近更新 更多