C# 存储过程与XML

C# 存储过程与XML,c#,asp.net,sql-server,xml,stored-procedures,C#,Asp.net,Sql Server,Xml,Stored Procedures,我得到这个错误: The error description is 'Only one top level element is allowed in an XML document.'. Could not find prepared statement with handle 0. The XML parse error 0xc00ce555 occurred on line number 1, near the XML text "<value1>34</value1&g

我得到这个错误:

The error description is 'Only one top level element is allowed in an XML document.'.
Could not find prepared statement with handle 0.
The XML parse error 0xc00ce555 occurred on line number 1, near the XML text "<value1>34</value1><value1>33</value1><value1>32</value1>".
The statement has been terminated. 
但如果我使用嵌入的输入字符串修改SP,它确实可以工作:

ALTER PROCEDURE dbo.VisibleFromList
(
    @XMLDoc   xml,
    @state     BIT
)

AS
BEGIN


DECLARE @docHandle int
EXEC sp_xml_preparedocument @docHandle OUTPUT, 
'<values>
 <value1>33</value1>
<value1>34</value1>  
</values>'

UPDATE tbh_Comments
SET Visible = @state WHERE 
CommentID IN (SELECT * FROM OPENXML(@docHandle, '/values/value1', 2) WITH (value1 INT '.'))


END

如何使其与输入参数一起工作?

您确定您的评论列表如您所述吗

//commentList =<values><value1>34</value1><value1>33</value1><value1>32/value1></values>
如果您的列表确实与此类似,那么它应该会起作用

根据您的错误,该元素可能不存在:

near the XML text "<value1>34</value1><value1>33</value1><value1>32</value1>".

你肯定你的评论列表和你描述的一样吗

//commentList =<values><value1>34</value1><value1>33</value1><value1>32/value1></values>
如果您的列表确实与此类似,那么它应该会起作用

根据您的错误,该元素可能不存在:

near the XML text "<value1>34</value1><value1>33</value1><value1>32</value1>".

如果你在做某种循环,我发现这样做很有帮助:

XElement entityListElement = new XElement("values");
XElement entityElement = new XElement(
                    "value",
                    new XElement("value1", "15"));
entityListElement.Add(entityElement);
然后传入entityListElement.ToString


这也使更改变得更容易,并让.NET为您生成XML。

如果您正在进行某种循环,我发现这样做很有帮助:

XElement entityListElement = new XElement("values");
XElement entityElement = new XElement(
                    "value",
                    new XElement("value1", "15"));
entityListElement.Add(entityElement);
然后传入entityListElement.ToString


这也使更改变得更容易,并让.NET为您生成XML。

我建议您将您的过程转换为使用。与sp_prepare_文档不同的是,它们是由SQL引擎本地实现的,它们可以更好地与查询进行交互,生成更好的错误消息,并且您可以使用它们

因此,在您的程序中,您可以执行以下操作:

declare @XMLDoc xml;
select @XMLDoc =N'<values>
 <value1>33</value1>
<value1>34</value1>  
</values>';


UPDATE tbh_Comments
SET Visible = @state WHERE 
CommentID IN (
    SELECT v.value('.', 'INT') as CommentID
    FROM @XMLDoc.nodes('/values/value1') t(v))

我建议您将您的过程转换为使用。与sp_prepare_文档不同的是,它们是由SQL引擎本地实现的,它们可以更好地与查询进行交互,生成更好的错误消息,并且您可以使用它们

因此,在您的程序中,您可以执行以下操作:

declare @XMLDoc xml;
select @XMLDoc =N'<values>
 <value1>33</value1>
<value1>34</value1>  
</values>';


UPDATE tbh_Comments
SET Visible = @state WHERE 
CommentID IN (
    SELECT v.value('.', 'INT') as CommentID
    FROM @XMLDoc.nodes('/values/value1') t(v))
试试这个

ALTER PROCEDURE dbo.VisibleFromList (
    @XMLDoc   xml,
    @state     BIT )

AS BEGIN


DECLARE @docHandle int EXEC sp_xml_preparedocument @docHandle OUTPUT, @XMLDoc 


 UPDATE tbh_Comments SET Visible = @state WHERE  CommentID IN (SELECT * 
 FROM OPENXML(@docHandle, '/root/values/value1', 2) WITH (value1 INT '.'))


END
试试这个

ALTER PROCEDURE dbo.VisibleFromList (
    @XMLDoc   xml,
    @state     BIT )

AS BEGIN


DECLARE @docHandle int EXEC sp_xml_preparedocument @docHandle OUTPUT, @XMLDoc 


 UPDATE tbh_Comments SET Visible = @state WHERE  CommentID IN (SELECT * 
 FROM OPENXML(@docHandle, '/root/values/value1', 2) WITH (value1 INT '.'))


END

您必须使用SQL 2000吗?如果不是,请使用本机SQL XML方法而不是XML prepare Document什么是本机SQL XML?必须使用SQL 2000吗?如果不是,请使用本机SQL XML方法,而不是XML prepare Document。您认为本机SQL XML是什么意思?以我的经验,是的,大多数时候更快。以我的经验,是的,大多数时候更快。是否将entityListElement传递给存储过程作为XML参数?因为它给出了一个错误:对象必须实现IConvertible。我在代码中添加了如何调用它,因为我注意到它与您的不同。我不知道这是否会导致错误,但是。。。如果有帮助的话,我还将System.Xml.Linq用于XElements。我很愚蠢,直到最近才意识到你没有使用Linq。您可以使用我在上面编辑的.ToString来获取所需内容。是否将entityListElement传递给存储过程作为XML参数?因为它给出了一个错误:对象必须实现IConvertible。我在代码中添加了如何调用它,因为我注意到它与您的不同。我不知道这是否会导致错误,但是。。。如果有帮助的话,我还将System.Xml.Linq用于XElements。我很愚蠢,直到最近才意识到你没有使用Linq。您可以使用我在上面编辑的.ToString来获取所需内容。