【问题标题】:MSSQL update multiple records all at once by one stored procedureMSSQL通过一个存储过程一次更新多条记录
【发布时间】:2019-02-06 13:00:02
【问题描述】:

我有一个当前看起来像这样的存储过程:

create procedure zsp_updateTyp5Graph
(
    @DayList nvarchar(1000),
    @Sales int,
    @SearchedUserId int
)
as 
update SearchedUserGraphData
    set SalesForDay=@Sales
where Day in (SELECT * FROM dbo.SplitString(@DayList)) and SearchedUserId=@SearchedUserId

daylist 参数如下所示:

0,1,2,3,4,5,6

我的 SearchedUserGraphData 表中有两列和 7 条记录(7 天)需要更新。例如:

   Day    Sales
    0       5
    1       6
    2       4
    3       3
    4       7
    5       9 
    6      11

我通过传递天数列表“部分”解决了这个问题......但我无法找出如何将这个 @DayList 参数与销售数据配对......

我创建了一个 SplitString 函数,看起来像这样用于匹配 DB 中的记录:

ALTER FUNCTION [dbo].[splitstring] ( @stringToSplit VARCHAR(MAX) )
RETURNS
    @returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN

    DECLARE @name NVARCHAR(255)
    DECLARE @pos INT

    WHILE CHARINDEX(',', @stringToSplit) > 0
    BEGIN
        SELECT @pos  = CHARINDEX(',', @stringToSplit)  
        SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

        INSERT INTO @returnList 
        SELECT @name

        SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
    END

    INSERT INTO @returnList
    SELECT @stringToSplit

    RETURN
END

现在的问题是我需要以某种方式从我的 C# 应用程序组合的 Days 列表及其相应的销售额中传递,然后一次更新所有记录,而不调用该过程 7 次来更新 7 条记录(这将是灾难性的从我眼中的性能角度来看)...

有人可以帮我解决这个问题吗?

附:伙计们,我对此的“最佳”想法是:

daylist 参数如下所示:

    0,1,2,3,4,5,6

And then sales:

    11,22,44,55,66,77,88

这是我可以传递销售额和天数参数的方式...但是然后呢?我不知道哪一天对应什么销售......

我可以在我的 C# 应用程序中形成一个键值对字典字符串,例如:

{ Day: 1 Sales: 44, Day: 2 Sales: 55 } 

这就是我可以形成字符串的方式。但是我需要在 MSSQL 中分解这个字符串以匹配 => day 1 => update with sales 44 ...

【问题讨论】:

  • 您可以将 DayList 作为表格参数发送
  • @hardkoded 是的,但我需要以某种方式匹配销售数天...我不知道该怎么做;/
  • @hardkoded 看到我更新的问题,我们可以在 mssql 中做类似的事情吗?

标签: c# asp.net sql-server sql-server-2008 stored-procedures


【解决方案1】:

您可以创建一个 SalesPerDay 类型

CREATE TYPE [dbo].[SalesPerDay] AS TABLE (
    day INT NOT NULL,
    sales INT NOT NULL
);

那么,你的 proc 应该是这样的

create procedure zsp_updateTyp5Graph
(
@DayList SalesPerDay READONLY,
@SearchedUserId int
)
as 
update SearchedUserGraphData
set SalesForDay=dayList.sales
FROM SearchedUserGraphData baseTable
   INNER JOIN @DayList dayList ON dayList.day = baseTable.day
WHERE SearchedUserId=@SearchedUserId

从 C# 中,您可以构建一个 DataTable 并将其发送到 proc。

var table = new DataTable();
table.Columns.Add("day", typeof(int));
table.Columns.Add("sales", typeof(int));

//Add data
table.Rows.Add(new []{1, 200});
table.Rows.Add(new []{2, 200});

//More code
Command.Parameters.AddWithValue("@DayList", table);

【讨论】:

  • 嘿顺便说一句。您是否也可以通过传递数据表来包含解决方案?只是一个样本,所以我可以加快他们的进程?我以前没有使用过将数据表作为参数传递...我觉得这样做会犯很多错误..
  • hardkoded,当尝试使用您上面提供的程序更改程序时,我收到错误消息:Msg 137, Level 15, State 2, Procedure zsp_updateTyp5Graph, Line 8 [Batch Start Line 0] 必须声明标量变量“@Sales”。
  • 完成,修复销售问题
  • 嘿顺便说一句...我试过这样调用程序: using(var ctx = new context() { ctx.zsp_updateTyp5Graph() }; 这里唯一可见的参数是 searcedduserid...不允许我传递数据表参数?:/
  • 我希望...这似乎比执行自定义 sql 命令 C# 代码更容易,只需简单地调用该过程.. 但它不允许传递数据表参数.. 它根本不将其视为参数:/
猜你喜欢
  • 2019-08-22
  • 1970-01-01
  • 1970-01-01
  • 2014-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多