【问题标题】:Passing an array of objects to SQL stored procedure将对象数组传递给 SQL 存储过程
【发布时间】:2015-09-20 04:57:19
【问题描述】:

我有两张桌子

  • paymentpayment_id、otherCosts、GarageCosts)
  • spareparts(payment_id、sparepartId、sparePartQty)

payment 表中payment_id 是自动生成的。除了 otherCostsgaragecosts 值之外,在我的 C# asp.net 应用程序中,还有一个带有

的对象数组
{ sparepartId : 'Somevalue', sparePartQty : 'somevalue' }

我需要做的是在存储过程中首先将记录输入到支付表中,其中包含车库成本和其他成本值。然后返回最后生成的付款 ID,并将其作为数组中每个值对的paymentId 输入到spareParts 表中。

实现这一目标的方法是什么?请帮忙。

【问题讨论】:

  • 查看表值参数 - SQL ServerADO.Net。这些是设计来保存多个值的类型(SQL Server 没有数组的概念)
  • 您需要将多条记录插入payment 表并将它们各自的记录插入spareparts,还是只插入一条payment 和它各自的spareparts

标签: c# sql asp.net arrays sql-server


【解决方案1】:

根据您的标签,我假设我们正在谈论 SQL Server / T-SQL。
您可以在一个存储过程中完成所有这些操作:

CREATE PROCEDURE dbo.Foo ... /* input parameters */
AS
BEGIN
    DECLARE @PaymentId int

    INSERT INTO payment(otherCosts, GarageCosts) VALUES (...)
    SET @PaymentId = SCOPE_IDENTITY()
    INSERT INTO spareparts(payment_id, sparepartId, sparePartQty) VALUES(@PaymentId, ...) 

END
GO

您可能还想查看@@IDENTITY,但请确保您阅读了@@IDENTITYSCOPE_IDENTITY 并了解与第一个相关的风险。

如果您需要两个独立的存储过程,您也可以这样做,这是第一个存储过程的外观。请注意,@PaymentId 是一个输出参数,这意味着调用者可以检索它并将其传递给第二个过程。

CREATE PROCEDURE dbo.Foo 
    /* input parameters */
    @PaymentId int OUT
AS
BEGIN
    INSERT INTO payment(otherCosts, GarageCosts) VALUES (...)
    SET @PaymentId = SCOPE_IDENTITY()
END
GO

编辑 - 在澄清问题范围后:

如果您需要调用第二个存储过程并向其传递参数数组,对于 SQL Server 2008 或更高版本,您可以使用 TVP(表值参数)。要了解如何在存储过程中使用它们以及如何从 C# 代码中传递它们,请参阅 Table Value Parameters in SQL Server 2008 and .NET (C#)Table-Valued Parameters
您也可以将 TVP 与只有一个存储过程的解决方案一起使用。

【讨论】:

  • 感谢您的快速回复。如果我的 paymentId 在第二个表中只有一条记录,您的代码就可以解决问题。但是我需要在第一个表中使用一个 paymentId,我需要在第二个表中输入多条记录。好像我需要2个SP
【解决方案2】:

要解决你的问题,试试这个

首先使用otherCostsGarageCosts 将数据插入payment 表中。

然后创建一个过程从payment表中获取最新存储的payment_id

create procedure select_last_payment_id
as
begin
    select top 1 payment_id
    from payment
    order by payment_id desc  
end

通过运行存储过程并将其分配给spareparts 表中的payment_id 并存储spareparts 数据,最后得到payment_id

希望它对你有用。

【讨论】:

  • 这可能无法在多线程环境中运行,或者如果此代码在可以同时为多个客户端提供服务的服务器(如 Web 前端服务器)上运行。当过程select_last_payment_id 运行时,另一个线程可能已经添加了另一行。还有一个基于@@IDENTITY 或 SCOPE_IDENTITY() 的更简单的建立模式。
  • @TFrost 和我对 Ladi 提到的一样。我的问题是没有得到lastiD。我需要使用第一个表的 lastId 向第二个表输入多条记录
  • @IsankaLakshan:对不起,我误解了这个问题。
猜你喜欢
  • 2014-08-29
  • 1970-01-01
  • 1970-01-01
  • 2016-04-27
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
相关资源
最近更新 更多