将两个逗号分隔的参数作为输入更新表格
本文关键字:参数 输入 表格 更新 分隔 两个 | 更新日期: 2023-09-27 17:57:43
我在前端有一个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,
'<root><s>' +
REPLACE(@sID, ',', '</s><s>') +
'</s></root>');
DECLARE @sOrderASXml xml = CONVERT(xml,
'<root><s>' +
REPLACE(@sOrder, ',', '</s><s>') +
'</s></root>');
;WITH ParsedIDs
AS
(
SELECT ID = T.c.value('.','varchar(20)'),
ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS RowNumber
FROM @sIDASXml.nodes('/root/s') T(c)
), ParsedOrders
AS
(
SELECT "Order" = T.c.value('.','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;
实时演示
然后你可以把它放在一个存储过程或其他什么东西里。
请注意:您不需要手动完成所有这些操作,应该通过某种方式使此网格视图通过数据绑定自动更新底层数据表。你应该寻找这样的东西,而不是所有这些痛苦。
您可以使用表值参数来避免向数据库发送分隔符分隔的值甚至XML。要做到这一点,你需要:
-
在数据库中声明一个参数类型,如下所示:
CREATE TYPE UpdateOrderType TABLE (ID int, Order int)
-
之后,您可以定义将参数用作的程序
CREATE PROCEDURE UpdateOrder (@UpdateOrderValues UpdateOrderType readonly) AS BEGIN UPDATE t SET OrderID = tvp.Order FROM <YourTable> t INNER JOIN @UpdateOrderValues tvp ON t.ID=tvp.ID END
正如您所看到的,与解析XML或分隔字符串相比,SQL是微不足道的。
-
使用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<OrderData> 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及更高版本)使将结构化数据作为参数传递给过程变得更容易、更正式。更重要的是,您一直在处理类型安全问题,因此在string/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