如何创建一个接受 XML 并使用该 xml 作为更新的存储过程 +使用 ado.net 调用此存储过程?
我正在使用 ms sql server 2005,我想进行批量更新。我想我可以通过将 xml 文档发送到存储过程来做到这一点。
所以我看到了很多关于如何插入的示例,
CREATE PROCEDURE [dbo].[spTEST_InsertXMLTEST_TEST](@UpdatedProdData XML)
AS
INSERT INTO
dbo.UserTable(CreateDate)
SELECT
@UpdatedProdData.value('(/ArrayOfUserTable/UserTable/CreateDate)[1]', 'DATETIME')
但我不确定更新会是什么样子。
我也不确定如何通过 ado.net 传入 xml?我是通过参数将其作为字符串传递还是什么?
我知道 sqlDataApater 有批量更新方法,但我正在使用 linq to sql。所以我宁愿继续使用它。因此,如果这有效,我将能够使用 linq to sql 获取所有记录并将它们作为对象。然后操作对象并使用 xml 序列化。
最后我可以使用 ado.net simple 将 xml 发送到服务器。这可能比 sqlDataAdapter 慢,但如果我可以继续使用对象,我愿意接受这种打击。
编辑
好的,到目前为止我已经有了
这是我的 XML
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfUserTable xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<UserTable>
<CreateDate>2011-05-21T11:04:55.0584669-07:00</CreateDate>
<id>0</id>
<AnotherField>false</AnotherField>
</UserTable>
<UserTable>
<CreateDate>2015-05-21T11:04:55.061467-07:00</CreateDate>
<id>0</id>
<AnotherField>true</AnotherField>
</UserTable>
</ArrayOfUserTable>
出现两个问题,第一个是
XML解析:第1行,第39个字符, 无法切换编码
第二个问题是日期。
转换时转换失败 来自字符串的日期时间。
这是我的 C# 代码。
using (TestDataContext db = new TestDataContext())
{
UserTable[] testRecords = new UserTable[2];
for (int count = 0; count < 2; count++)
{
UserTable testRecord = new UserTable();
if (count == 1)
{
testRecord.CreateDate = DateTime.Now.AddYears(5);
testRecord.AnotherField = true;
}
else
{
testRecord.CreateDate = DateTime.Now.AddYears(1);
testRecord.AnotherField = false;
}
testRecords[count] = testRecord;
}
StringBuilder sBuilder = new StringBuilder();
System.IO.StringWriter sWriter = new System.IO.StringWriter(sBuilder);
XmlSerializer serializer = new XmlSerializer(typeof(UserTable[]));
serializer.Serialize(sWriter, testRecords);
using (SqlConnection con = new SqlConnection(connectionString))
{
string sprocName = "spTEST_UpdateTEST_TEST";
using (SqlCommand cmd = new SqlCommand(sprocName, con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
SqlParameter param1 = new SqlParameter("@UpdatedProdData", SqlDbType.VarChar, int.MaxValue);
param1.Value = sBuilder.ToString();
cmd.Parameters.Add(param1);
con.Open();
int result = cmd.ExecuteNonQuery();
con.Close();
}
}
}
因此,为了解决这两个问题,我只是手工编写了一个小的 xml 文件,该文件顶部没有 xml 标签,并且所有日期只有 MM/DD/YYYY 才能使之满意。
但它仍然不起作用
USE [Test]
GO
/****** Object: StoredProcedure [dbo].[spTEST_UpdateTEST_TEST] Script Date: 05/21/2010 11:10:20 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[spTEST_UpdateTEST_TEST](@UpdatedProdData XML)
AS
UPDATE dbo.UserTable
SET CreateDate = @UpdatedProdData.value('(/ArrayOfUserTable/UserTable/CreateDate)[1]', 'DATETIME')
WHERE AnotherField = @UpdatedProdData.value('(/ArrayOfUserTable/UserTable/AnotherField)[1]', 'bit')
这甚至没有更新任何记录。另外,我仍然认为这只能处理一条记录,所以我不确定如何更改它以更新许多记录。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
要从直接 ADO.NET 调用存储过程,您可以使用标准的 ADO.NET 内容,因为任何有关 .NET 数据访问的编程书籍或 ADO.NET 教程(仅限 Google!)都会教您:
当然,您可能想将其包装到 try...catch 块中以进行异常处理等 - 但这基本上是您需要使用直接 ADO.NET 调用该存储过程的代码。
更新:为了从 XML 更新表,您应该查看 XQuery 中的
.nodes()
函数并编写如下更新语句:基本上,您将 XML 分解为名为
tbl(UPD)
的“虚拟”表 -
标记的每个条目现在都是该虚拟表中的一个“行” (因此您可以处理许多行),然后从该虚拟行获取数据来更新您的基表。有关 SQL Server 2005 及更高版本中 SQL-XML XQuery 的真正精彩介绍,请查看这篇 15 秒 - 它极大地帮助我掌握了 XQuery 的可能性,以及如何在 SQL Server 的 XQuery 实现中做到这一点。
To call the stored proc from straight ADO.NET, you'd use the standard ADO.NET stuff as any programming book on .NET data access or ADO.NET tutorial (just Google for that!) will teach you:
Of course, you might want to wrap this into a try...catch block for exception handling and so forth - but that's basically the code you'd need to call that stored proc using straight ADO.NET.
UPDATE: in order to update your table from the XML, you should check out the
.nodes()
function in XQuery and write your update statement something like this:Basically, you're shredding your XML into a "virtual" table called
tbl(UPD)
- each entry of an<UserTable>
tag now is a "row" in that virtual table (thus you can handle many rows), and you grab data from that virtual row to update your base table.For a really good introduction to SQL-XML XQuery in SQL Server 2005 and up, check out this article on 15 Seconds - it's helped me tremendously to get a grasp on what is possible with XQuery, and how to do it in SQL Server's XQuery implementation.
我认为您可以将 XML 放入临时表中,然后将其用于存储过程的更新部分。但不确定这是否能回答问题!
I think you could get the XML into temp table and then use it into update part of the stored procedure. Not sure if that answers the questions though!
为此,将 XMLDOC1 作为过程中的参数传递。
在你的.net代码中写入dataset.Writexml
这将赋予字符串变量并将该字符串作为参数传递给过程。
下面是如何在过程中获取数据的示例。
@XMLDoc1 as text
声明 @idoc1 as int
EXEC sp_xml_preparedocument @idoc1 OUTPUT, @XMLDoc1
Select * into #TableName
FROM OPENXML(@idoc1,'/NewDataSet/Tablename',2)
WITH(表结构如下)
(PrefDetailID int
,PrefID int )
--select * from #TableName
EXEC sp_xml_removedocument @idoc1
现在您已在 #TableName 中获取了所有数据,并按照您喜欢的方式在程序中进行任何插入或更新操作
或查看下面的链接这是我自己的博客
http://sqlmca.wordpress.com/2009/07/29/how-to-get-data-from-dataset-into-sqlserver-table-by-using-openxml-method/
for that pass the XMLDOC1 as your parameter in procedure.
in you .net code write dataset.Writexml
and that will give to string variable and pass that string to the procedure as parameter.
below is the example of how you get data in procedure.
@XMLDoc1 as text
DECLARE @idoc1 as int
EXEC sp_xml_preparedocument @idoc1 OUTPUT, @XMLDoc1
Select * into #TableName
FROM OPENXML(@idoc1,'/NewDataSet/Tablename',2)
WITH (structure of Table like below)
(PrefDetailID int
,PrefID int )
--select * from #TableName
EXEC sp_xml_removedocument @idoc1
now you got all your data in the #TableName and manipulte as you like in procedure do any thing insert or update
or check below link this my own blog
http://sqlmca.wordpress.com/2009/07/29/how-to-get-data-from-dataset-into-sqlserver-table-by-using-openxml-method/