从两个逗号分隔的参数更新表作为输入

我在前端有一个Gridview,其中Grid有两列:ID和Order,如下所示:

ID Order 1 1 2 2 3 3 4 4 

现在用户可以像前端Gridview一样更新订单:

 ID Order 1 2 2 4 3 1 4 3 

现在,如果用户单击“保存”按钮,则ID和订单数据将作为@sID =(1,2,3,4)和@sOrder =(2,4,1,3)发送到存储过程

现在,如果我想更新订单并进行保存,我想将其存储到数据库中。 通过存储过程如何更新到表中以便更新表,而选择它时会给我以下结果:

 ID Order 1 2 2 4 3 1 4 3 

没有内置函数来解析这些逗号分隔的字符串。 但是,您可以使用SQL Server中的XML函数来执行此操作。 就像是:

 DECLARE @sID VARCHAR(100) = '1,2,3,4'; DECLARE @sOrder VARCHAR(10) = '2,4,1,3'; DECLARE @sIDASXml xml = CONVERT(xml, '' + REPLACE(@sID, ',', '') + ''); DECLARE @sOrderASXml xml = CONVERT(xml, '' + REPLACE(@sOrder, ',', '') + ''); ;WITH ParsedIDs AS ( SELECT ID = Tcvalue('.','varchar(20)'), ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS RowNumber FROM @sIDASXml.nodes('/root/s') T(c) ), ParsedOrders AS ( SELECT "Order" = Tcvalue('.','varchar(20)'), ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS RowNumber FROM @sOrderASXml.nodes('/root/s') T(c) ) UPDATE t SET t."Order" = p."Order" FROM @tableName AS t INNER JOIN ( SELECT i.ID, p."Order" FROM ParsedOrders p INNER JOIN ParsedIDs i ON p.RowNumber = i.RowNumber ) AS p ON t.ID = p.ID; 

现场演示

然后你可以把它放在存储过程或其他什么。

请注意:您不需要手动完成所有这些操作,它应该是某种方式使此gridview通过数据绑定自动更新基础数据表。 你应该搜索这样的东西,而不是所有这些痛苦。

您可以使用表值参数来避免将分隔符分隔值甚至XML发送到数据库。 为此,您需要:

  1. 在数据库中声明参数类型,如下所示:

     CREATE TYPE UpdateOrderType TABLE (ID int, Order int) 
  2. 之后,您可以定义将参数用作的过程

     CREATE PROCEDURE UpdateOrder (@UpdateOrderValues UpdateOrderType readonly) AS BEGIN UPDATE t SET OrderID = tvp.Order FROM  t INNER JOIN @UpdateOrderValues tvp ON t.ID=tvp.ID END 

    如您所见,与解析XML或分隔字符串相比,SQL是微不足道的。

  3. 使用C#中的参数:

     using (SqlCommand command = connection.CreateCommand()) { command.CommandText = "dbo.UpdateOrder"; command.CommandType = CommandType.StoredProcedure; //create a table from your gridview data DataTable paramValue = CreateDataTable(orderedData) SqlParameter parameter = command.Parameters .AddWithValue("@UpdateOrderValues", paramValue ); parameter.SqlDbType = SqlDbType.Structured; parameter.TypeName = "dbo.UpdateOrderType"; command.ExecuteNonQuery(); } 

    其中CreateDataTable是这样的:

     //assuming the source data has ID and Order properties private static DataTable CreateDataTable(IEnumerable source) { DataTable table = new DataTable(); table.Columns.Add("ID", typeof(int)); table.Columns.Add("Order", typeof(int)); foreach (OrderData data in source) { table.Rows.Add(data.ID, data.Order); } return table; } 

    (代码解除了这个问题 )

正如您所看到的,这种方法(特定于SQL-Server 2008及更高版本)使得将结构化数据作为参数传递给过程变得更容易和更正式。 更重要的是,你一直在使用类型安全,因此在字符串/ xml操作中出现的大部分解析错误都不是问题。

你可以使用charindex之类的

 DECLARE @id VARCHAR(MAX) DECLARE @order VARCHAR(MAX) SET @id='1,2,3,4,' SET @order='2,4,1,3,' WHILE CHARINDEX(',',@id) > 0 BEGIN DECLARE @tmpid VARCHAR(50) SET @tmpid=SUBSTRING(@id,1,(charindex(',',@id)-1)) DECLARE @tmporder VARCHAR(50) SET @tmporder=SUBSTRING(@order,1,(charindex(',',@order)-1)) UPDATE dbo.Test SET [Order]=@tmporder WHERE ID=convert(int,@tmpid) SET @id = SUBSTRING(@id,charindex(',',@id)+1,len(@id)) SET @order=SUBSTRING(@order,charindex(',',@order)+1,len(@order)) END