使用XML数据更新Database中的行
本文关键字:Database 更新 XML 数据 使用 | 更新日期: 2023-09-27 18:04:38
这是我第一次使用XML向表中插入数据。我保存数据从前端(所有的Datagridview行)到一个xml文件,并将其发送到数据库插入到表SD_ShippingDetails。下面是读取XML数据和保存数据的查询。正如您可以从查询中看到的,我正在删除相关的ShippingID详细信息并再次插入。(删除SD_ShippingDetails中ShippingID=@ShippingID)。我们可以通过从XML中获取数据来更新SD_ShippingDetails中已经存在的行吗?如果是,请帮助我查询。
CREATE PROCEDURE SD_Insert_ShippingDetails
@PBMXML as varchar(Max),
@ShippingID as INT
AS
BEGIn
declare @i int
exec sp_xml_preparedocument @i output,@PBMXML
DELETE FROM SD_ShippingDetails WHERE ShippingID=@ShippingID
INSERT INTO SD_ShippingDetails(ShippingID,Weight,Height,TotalBoxes,Price)
SELECT ShippingID,Weight,Height,TotalBoxes,Price FROM OPENXML(@i,'Root/ShippingBox',2)
WITH (
ShippingID int,Weight varchar(20),Height varchar(20),TotalBoxes varchar(20),Price numeric(18,2))
exec sp_xml_removedocument @i
END
谢谢。
你是在SQL Server 2005上,所以你可以使用XML数据类型而不是openxml,所以这个答案使用它。解决方案不需要使用XML数据类型。如果您愿意,可以使用openxml重写。
您在注释中指定了SD_ShippingDetails中有一个ID标识字段(我假设这是主键),但您也说ShippingID和Weight的组合是唯一的。剩下的表结构是这样的:
create table dbo.SD_ShippingDetails
(
ID int identity primary key,
ShippingID int not null,
Weight varchar(20) not null,
Height varchar(20),
TotalBoxes varchar(20),
Price numeric(18,2),
unique (ShippingID, Weight)
);
存储过程首先需要更新SD_ShippingDetails中已经存在的所有行,然后需要插入缺失的行。
create procedure dbo.SD_Insert_ShippingDetails
@PBMXML as xml
as
update dbo.SD_ShippingDetails
set Height = T.N.value('(Height/text())[1]', 'varchar(20)'),
TotalBoxes = T.N.value('(TotalBoxes/text())[1]', 'varchar(20)'),
Price = T.N.value('(Price/text())[1]', 'numeric(18,2)')
from @PBMXML.nodes('Root/ShippingBox') as T(N)
where ShippingID = T.N.value('(ShippingID/text())[1]', 'int') and
Weight = T.N.value('(Weight/text())[1]', 'varchar(20)');
insert into dbo.SD_ShippingDetails(ShippingID, Weight, Height, TotalBoxes, Price)
select T.N.value('(ShippingID/text())[1]', 'int'),
T.N.value('(Weight/text())[1]', 'varchar(20)'),
T.N.value('(Height/text())[1]', 'varchar(20)'),
T.N.value('(TotalBoxes/text())[1]', 'varchar(20)'),
T.N.value('(Price/text())[1]', 'numeric(18,2)')
from @PBMXML.nodes('Root/ShippingBox') as T(N)
where not exists (
select *
from dbo.SD_ShippingDetails
where ShippingID = T.N.value('(ShippingID/text())[1]', 'int') and
Weight = T.N.value('(Weight/text())[1]', 'varchar(20)')
);
SQL小提琴如果你使用的是Sql Server 2005,那么将值放在#temp或@variables表中是最好的。
使用2008及以上版本,您可以利用MERGE功能。
http://msdn.microsoft.com/en-us/library/bb522522 (v = sql.105) . aspx
这是一个很好的xml分解链接。注意,您使用的是旧版本的OPENXML。这是一个Sql Server 2000命令。查看下面Plamen的博客,了解2005年及以上的语法。
http://pratchev.blogspot.com/2007/06/shredding - xml -在- sql - server - 2005. - html
我会将您的XML填充到变量表中,然后使用Update
语句和Insert
与Not Exists
。
如果你有SQL 2008,你可以替换你的删除和插入语句…
MERGE SD_ShippingDetails AS Target
USING (SELECT ShippingID,
Weight,
Height,
TotalBoxes,
Price
FROM OPENXML(@i,'Root/ShippingBox',2)
WITH (ShippingID int,
Weight varchar(20),
Height varchar(20),
TotalBoxes varchar(20),
Price numeric(18,2)) ) AS source (ShippingID,Weight,Height,TotalBoxes,Price)
ON (target.ShippingID = source.ShippingID)
WHEN MATCHED THEN
UPDATE SET Weight = source.Weight,
Height = source.Height,
TotalBoxes = source.TotalBoxes,
Price = source.Price
WHEN NOT MATCHED THEN
INSERT (ShippingID,Weight,Height,TotalBoxes,Price)
VALUES (source.ShippingID,source.Weight,source.Height,source.TotalBoxes,source.Price);