通过存储过程使用 XML 更新 table 详细信息
Update table details using XML Through Stored Procedures
首先,我已经完成了关于这个主题的相关问题,但是 none 解决了我的问题,因为我的 xml 有一些不同的结构。这就是为什么我在这里问一个关于这个问题的问题。
<Root>
<MyData>
<Data>
<EID>1</EID>
<PID>246</PID>
<SID>1</SID>
</Data>
<UpdateData>
<TemplateID>42</TemplateID>
<UserID>12</UserID>
</UpdateData>
<UpdateData>
<TemplateID>55</TemplateID>
<UserID>2</UserID>
</UpdateData>
<UpdateData>
<TemplateID>61</TemplateID>
<UserID>2</UserID>
</UpdateData>
<UpdateData>
<TemplateID>66</TemplateID>
<UserID>2</UserID>
</UpdateData>
<UpdateData>
<TemplateID>76</TemplateID>
<UserID>2</UserID>
</UpdateData>
<UpdateData>
<TemplateID>79</TemplateID>
<UserID>2</UserID>
</UpdateData>
</MyData>
</Root>
我有一个像上面那样的 xml,我想使用特定条件从我的数据库 table 中的那个 XML 更新每个 UserId
。
我在下面包含了我的 table 结构
Table 姓名:UpdateDetails
列:EID, PID, SID, TemplateID, UserID
所有列都是 int
数据类型
正常查询会像下面这样
update UpdateDetails
set UserID = @UserID
where EID = @EID
and PID = @PID
and SID = @SID
and TemplateID = @TemplateID;
但我不知道如何获取 xml 中的所有值并进行更新。
我曾尝试过类似下面的方法,但它不起作用。
CREATE PROCEDURE Details
@xml text
AS
BEGIN
SET NOCOUNT ON;
Declare @intPointer int;
declare @PId int;
declare @EId int;
declare @SId int;
set @PId =(SELECT data.item.value('PID', 'int') AS PId
FROM @xml.nodes('/Root/MyData/Data') data(item));
set @EId =(SELECT data.item.value('EID', 'int') AS EId
FROM @xml.nodes('/Root/MyData/Data') Delegatedata(item));
set @SId =(SELECT data.item.value('SID', 'int') AS SId
FROM @xml.nodes('/Root/MyData/Data') data(item));
exec sp_xml_preparedocument @intPointer output, @xml
update UpdateDetails set UserID=
(Select *
from OpenXml(@intPointer,'/Root/MyData/Data',3)
With (UserID int 'UserID'))
where PID=@PID and SID=@SID and EID=@EID and TemplateID=(Select *
from OpenXml(@intPointer,'/Root/MyData/Data',3)
With (TemplateID int 'TemplateID'))
END
请帮我解决这个问题。任何帮助将不胜感激。
使用标准的本机 XQuery,您可以相当轻松地解析 XML:
DECLARE @input XML = '.... your XML .....'
SELECT
EID = XC.value('(EID)[1]', 'int'),
PID = XC.value('(PID)[1]', 'int'),
SID = XC.value('(SID)[1]', 'int'),
TemplateID = XUC.value('(TemplateID)[1]', 'int'),
UserID = XUC.value('(UserID)[1]', 'int')
FROM
@input.nodes('/Root/MyData/Data') AS XT(XC)
CROSS APPLY
@input.nodes('/Root/MyData/UpdateData') AS XUT(XUC)
这给你一个输出:
EID PID SID TemplateID UserID
------------------------------
1 246 1 42 12
1 246 1 55 2
1 246 1 61 2
1 246 1 66 2
1 246 1 79 2
基于此,您应该能够制定一个 UPDATE
语句来完成您需要它做的事情。
请:不要再使用TEXT
数据类型了!它已被弃用 - 因为这确实是 XML - 使用 XML
数据类型!
所以试试存储过程:
CREATE PROCEDURE Details
@input XML
AS
BEGIN
WITH XmlCte AS
(
SELECT
EID = XC.value('(EID)[1]', 'int'),
PID = XC.value('(PID)[1]', 'int'),
SID = XC.value('(SID)[1]', 'int'),
TemplateID = XUC.value('(TemplateID)[1]', 'int'),
UserID = XUC.value('(UserID)[1]', 'int')
FROM
@input.nodes('/Root/MyData/Data') AS XT(XC)
CROSS APPLY
@input.nodes('/Root/MyData/UpdateData') AS XUT(XUC)
)
UPDATE ud
SET UserID = x.UserID
FROM dbo.UpdateDetails ud
INNER JOIN XmlCte x ON ud.EID = x.EID
AND ud.PID = x.PID
AND ud.SID = x.SID
AND ud.TemplateID = x.TemplateID
END
XmlCte
CTE(通用 Table 表达式)基本上将 @Input
XML 解析为关系 table,然后应用 UPDATE
语句使用这些行作为值来更新您的 table with.
将列表传递给此方法以获取数据表
private DataTable GetSupplementaryLessonDataTable(List<SupplementaryLesson> supplementaryLessons)
{
DataTable dtsupplementaryLessons = new DataTable("supplementaryLessons");
dtsupplementaryLessons.Columns.Add(new DataColumn("LessonId",
Type.GetType("System.Int32")));
dtsupplementaryLessons.Columns.Add(new DataColumn("IsSmartSyllabus",
Type.GetType("System.Int32")));
foreach (var item in supplementaryLessons)
{
DataRow drRow = dtsupplementaryLessons.NewRow();
drRow["LessonId"] = item.Id;
drRow["IsSmartSyllabus"] = Convert.ToInt32(item.Value);
dtsupplementaryLessons.Rows.Add(drRow);
}
return dtsupplementaryLessons;
}
然后转换为 xml 并将其作为 SQL 参数传递
using (StringWriter swStringWriter = new StringWriter())
{
supplementaryLessonsDataTable.WriteXml(swStringWriter);
string strsupplementaryLessonsDataTable = swStringWriter.ToString();
Parameter[] lstParams = new Parameter[]
{
new Parameter("@supplementaryLessons",strsupplementaryLessonsDataTable,ParameterDirection.Input,DbType.Xml)
};
int intRetValue = DataBaseHelper.ExecuteNonQuery("Admin_UpdateBulkSupplementaryLesson", lstParams);
}
存储过程:
ALTER PROCEDURE Admin_UpdateBulkSupplementaryLesson
@EmpDetails xml
AS
BEGIN
WITH XmlCte AS
(
SELECT
CAST(colx.query('data(LessonId)') AS varchar) AS LessonId,
CAST(colx.query('data(IsSmartSyllabus)') AS varchar) AS IsSmartSyllabus
FROM
@EmpDetails.nodes('DocumentElement/supplementaryLessons') AS TABX(COLX)
)
UPDATE L
SET L.IsSmartSyllabus = x.IsSmartSyllabus
FROM Lesson L
INNER JOIN XmlCte x ON L.LessonId = x.LessonId
END
首先,我已经完成了关于这个主题的相关问题,但是 none 解决了我的问题,因为我的 xml 有一些不同的结构。这就是为什么我在这里问一个关于这个问题的问题。
<Root>
<MyData>
<Data>
<EID>1</EID>
<PID>246</PID>
<SID>1</SID>
</Data>
<UpdateData>
<TemplateID>42</TemplateID>
<UserID>12</UserID>
</UpdateData>
<UpdateData>
<TemplateID>55</TemplateID>
<UserID>2</UserID>
</UpdateData>
<UpdateData>
<TemplateID>61</TemplateID>
<UserID>2</UserID>
</UpdateData>
<UpdateData>
<TemplateID>66</TemplateID>
<UserID>2</UserID>
</UpdateData>
<UpdateData>
<TemplateID>76</TemplateID>
<UserID>2</UserID>
</UpdateData>
<UpdateData>
<TemplateID>79</TemplateID>
<UserID>2</UserID>
</UpdateData>
</MyData>
</Root>
我有一个像上面那样的 xml,我想使用特定条件从我的数据库 table 中的那个 XML 更新每个 UserId
。
我在下面包含了我的 table 结构
Table 姓名:UpdateDetails
列:EID, PID, SID, TemplateID, UserID
所有列都是 int
数据类型
正常查询会像下面这样
update UpdateDetails
set UserID = @UserID
where EID = @EID
and PID = @PID
and SID = @SID
and TemplateID = @TemplateID;
但我不知道如何获取 xml 中的所有值并进行更新。
我曾尝试过类似下面的方法,但它不起作用。
CREATE PROCEDURE Details
@xml text
AS
BEGIN
SET NOCOUNT ON;
Declare @intPointer int;
declare @PId int;
declare @EId int;
declare @SId int;
set @PId =(SELECT data.item.value('PID', 'int') AS PId
FROM @xml.nodes('/Root/MyData/Data') data(item));
set @EId =(SELECT data.item.value('EID', 'int') AS EId
FROM @xml.nodes('/Root/MyData/Data') Delegatedata(item));
set @SId =(SELECT data.item.value('SID', 'int') AS SId
FROM @xml.nodes('/Root/MyData/Data') data(item));
exec sp_xml_preparedocument @intPointer output, @xml
update UpdateDetails set UserID=
(Select *
from OpenXml(@intPointer,'/Root/MyData/Data',3)
With (UserID int 'UserID'))
where PID=@PID and SID=@SID and EID=@EID and TemplateID=(Select *
from OpenXml(@intPointer,'/Root/MyData/Data',3)
With (TemplateID int 'TemplateID'))
END
请帮我解决这个问题。任何帮助将不胜感激。
使用标准的本机 XQuery,您可以相当轻松地解析 XML:
DECLARE @input XML = '.... your XML .....'
SELECT
EID = XC.value('(EID)[1]', 'int'),
PID = XC.value('(PID)[1]', 'int'),
SID = XC.value('(SID)[1]', 'int'),
TemplateID = XUC.value('(TemplateID)[1]', 'int'),
UserID = XUC.value('(UserID)[1]', 'int')
FROM
@input.nodes('/Root/MyData/Data') AS XT(XC)
CROSS APPLY
@input.nodes('/Root/MyData/UpdateData') AS XUT(XUC)
这给你一个输出:
EID PID SID TemplateID UserID
------------------------------
1 246 1 42 12
1 246 1 55 2
1 246 1 61 2
1 246 1 66 2
1 246 1 79 2
基于此,您应该能够制定一个 UPDATE
语句来完成您需要它做的事情。
请:不要再使用TEXT
数据类型了!它已被弃用 - 因为这确实是 XML - 使用 XML
数据类型!
所以试试存储过程:
CREATE PROCEDURE Details
@input XML
AS
BEGIN
WITH XmlCte AS
(
SELECT
EID = XC.value('(EID)[1]', 'int'),
PID = XC.value('(PID)[1]', 'int'),
SID = XC.value('(SID)[1]', 'int'),
TemplateID = XUC.value('(TemplateID)[1]', 'int'),
UserID = XUC.value('(UserID)[1]', 'int')
FROM
@input.nodes('/Root/MyData/Data') AS XT(XC)
CROSS APPLY
@input.nodes('/Root/MyData/UpdateData') AS XUT(XUC)
)
UPDATE ud
SET UserID = x.UserID
FROM dbo.UpdateDetails ud
INNER JOIN XmlCte x ON ud.EID = x.EID
AND ud.PID = x.PID
AND ud.SID = x.SID
AND ud.TemplateID = x.TemplateID
END
XmlCte
CTE(通用 Table 表达式)基本上将 @Input
XML 解析为关系 table,然后应用 UPDATE
语句使用这些行作为值来更新您的 table with.
将列表传递给此方法以获取数据表
private DataTable GetSupplementaryLessonDataTable(List<SupplementaryLesson> supplementaryLessons)
{
DataTable dtsupplementaryLessons = new DataTable("supplementaryLessons");
dtsupplementaryLessons.Columns.Add(new DataColumn("LessonId",
Type.GetType("System.Int32")));
dtsupplementaryLessons.Columns.Add(new DataColumn("IsSmartSyllabus",
Type.GetType("System.Int32")));
foreach (var item in supplementaryLessons)
{
DataRow drRow = dtsupplementaryLessons.NewRow();
drRow["LessonId"] = item.Id;
drRow["IsSmartSyllabus"] = Convert.ToInt32(item.Value);
dtsupplementaryLessons.Rows.Add(drRow);
}
return dtsupplementaryLessons;
}
然后转换为 xml 并将其作为 SQL 参数传递
using (StringWriter swStringWriter = new StringWriter())
{
supplementaryLessonsDataTable.WriteXml(swStringWriter);
string strsupplementaryLessonsDataTable = swStringWriter.ToString();
Parameter[] lstParams = new Parameter[]
{
new Parameter("@supplementaryLessons",strsupplementaryLessonsDataTable,ParameterDirection.Input,DbType.Xml)
};
int intRetValue = DataBaseHelper.ExecuteNonQuery("Admin_UpdateBulkSupplementaryLesson", lstParams);
}
存储过程:
ALTER PROCEDURE Admin_UpdateBulkSupplementaryLesson
@EmpDetails xml
AS
BEGIN
WITH XmlCte AS
(
SELECT
CAST(colx.query('data(LessonId)') AS varchar) AS LessonId,
CAST(colx.query('data(IsSmartSyllabus)') AS varchar) AS IsSmartSyllabus
FROM
@EmpDetails.nodes('DocumentElement/supplementaryLessons') AS TABX(COLX)
)
UPDATE L
SET L.IsSmartSyllabus = x.IsSmartSyllabus
FROM Lesson L
INNER JOIN XmlCte x ON L.LessonId = x.LessonId
END