我正在使用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来实现sql。所以我宁愿继续使用它。所以,如果这有效,我将能够使用linq获取所有记录到sql并将它们作为对象。然后操纵对象并使用xml seralization。
最后我可以使用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')
这甚至不更新任何记录。此外,我仍然认为这只能处理一条记录,所以我不知道如何更改它以更新许多记录。
答案 0 :(得分:0)
要从直接的ADO.NET调用存储过程,你可以使用标准的ADO.NET内容作为任何关于.NET数据访问的编程书籍或ADO.NET教程(只有谷歌那样!)将教你:< / p>
using(SqlConnection con = new SqlConnection(your-connection-string-here))
{
string sprocName = "spTEST_InsertXMLTEST_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 = YourXmlValueHere;
cmd.Parameters.Add(param1);
con.Open();
int result = cmd.ExecuteNonQuery();
con.Close();
}
}
当然,您可能希望将其包装到try ... catch块中以进行异常处理等等 - 但这基本上是您需要使用直接ADO.NET调用该存储过程的代码。
UPDATE:为了从XML更新您的表,您应该查看XQuery中的.nodes()
函数并编写更新语句,如下所示:
UPDATE
dbo.UserTable
SET
CreateDate = tbl.UPD.value('(CreateDate)[1]', 'DATETIME')
FROM
@UpdatedProdData.nodes('/ArrayOfUserTable/UserTable') AS tbl(UPD)
WHERE
AnotherField = tbl.UPD.value('(AnotherField)[1]', 'bit')
基本上,您将XML分解为名为tbl(UPD)
的“虚拟”表 - <UserTable>
标记的每个条目现在都是该虚拟表中的“行”(因此您可以处理许多()行,并从该虚拟行中获取数据以更新基表。
为了在SQL Server 2005及更高版本中对SQL-XML XQuery进行非常好的介绍,请查看此article on 15 Seconds - 这对于了解XQuery的可能性以及如何在SQL Server的XQuery实现。
答案 1 :(得分:0)
我认为您可以将XML放入临时表中,然后将其用于更新存储过程的一部分。不确定是否能回答问题!
答案 2 :(得分:0)
为此传递XMLDOC1作为过程中的参数。 在.net代码中写入数据集.Writexml 这将赋予字符串变量并将该字符串作为参数传递给过程。 下面是如何在程序中获取数据的示例。 @ XMLDoc1 as text
DECLARE @ idoc1 as int
EXEC sp_xml_preparedocument @ idoc1 OUTPUT,@ XMLDoc1
选择*进入#TableName
FROM OPENXML(@ idoc1,'/ NewDataSet / Tablename',2)
WITH(表格结构如下)
(PrefDetailID int
,PrefID int)
- 从#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/