Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将NVARCHAR值转换为XML的最快方法_C#_Sql Server_Xml_Linq_Tsql - Fatal编程技术网

C# 将NVARCHAR值转换为XML的最快方法

C# 将NVARCHAR值转换为XML的最快方法,c#,sql-server,xml,linq,tsql,C#,Sql Server,Xml,Linq,Tsql,在我继承以支持的数据库中,有几个表具有一个NVARCHARMAX列,其中包含一个非类型化XML数据blob。我的任务是在这些XML blob中搜索对给定ID的引用,然后在找到第一个引用时停止,并报告找到的内容。我目前正在遍历每一行,将blob转换为XML,然后使用XQuery在blob中搜索ID 但是,由于表中有大量行,NVARCHAR值到XML的初始转换花费的时间太长。下面是我用来转换每个blob的代码示例,HistoryID是PK,值更改为从XMLData获取下一个XML blob: 我还尝

在我继承以支持的数据库中,有几个表具有一个NVARCHARMAX列,其中包含一个非类型化XML数据blob。我的任务是在这些XML blob中搜索对给定ID的引用,然后在找到第一个引用时停止,并报告找到的内容。我目前正在遍历每一行,将blob转换为XML,然后使用XQuery在blob中搜索ID

但是,由于表中有大量行,NVARCHAR值到XML的初始转换花费的时间太长。下面是我用来转换每个blob的代码示例,HistoryID是PK,值更改为从XMLData获取下一个XML blob:


我还尝试利用C和LINQ,但XML blob太大,无法从.NET来回传递到SQL Server。不幸的是,我也无法在不破坏应用程序的情况下修改现有表。是否有更好的方法将这些XML blob转换为可搜索的形式,或者我只是SOL?

SQL有处理数据库中XML的方法,例如值、存在、节点、查询和修改。然后,XML元素的value属性是可查询的。更多信息:

    // xmlElement is the column read from DB , consider having an index on the field as well as batching the reads if its too big   
    public static List<History> DeserializeHistory(XElement xmlElement)
    {

        System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(List<History>));

        using (System.Xml.XmlReader reader = xmlElement.CreateReader())
        {

            return (List<History>)serializer.Deserialize(reader);

        }

    }
比如:

SELECT 
CONVERT(XML, XMLData).value('(/Updated/UserId)[1]', 'int') AS UpdatedId 
FROM History
WHERE CONVERT(XML, XMLData).exist('(/Updated/UserId)[1]') > 0
如果某些xmldata Blob大到360mb,则必须尝试一下,看看会发生什么


为了提高性能,如果可以修改模式,可以将XML索引添加到表中。

无需循环。。。像这样试试

CREATE TABLE #tbl (ID INT,SomeColumn VARCHAR(100),YourXMLasString NVARCHAR(MAX));
INSERT INTO #tbl VALUES
 (1,'Test 11','<root><id>100</id><more>abc</more></root>')
,(2,'Test 12','<root><id>100</id><more>abc</more></root>')
,(3,'Test 21','<root><id>200</id><more>def</more></root>')
,(4,'Test 22','<root><id>200</id><more>def</more></root>')
,(5,'Test 23','<root><id>200</id><more>def</more></root>')
,(6,'Test  3','<root><id>300</id><more>ghi</more></root>');

--Just take the id 200
SELECT *
FROM #tbl
CROSS APPLY(SELECT CAST(YourXMLasString AS XML)) AS A(RealXml)
WHERE RealXml.exist('/root[id=200]') = 1

--Now stop at the first with 200
SELECT TOP 1 *
FROM #tbl
CROSS APPLY(SELECT CAST(YourXMLasString AS XML)) AS A(RealXml)
WHERE RealXml.exist('/root[id=200]') = 1
ORDER BY ID
GO

DROP TABLE #tbl;
用这个你可以创建一个边桌

CREATE TABLE #SideTable(RefID INT,RealXML XML);
INSERT INTO #SideTable
SELECT ID,CAST(YourXMLasString AS XML)
FROM #tbl;

SELECT * FROM #SideTable;

如果数据正在更改,您可能会考虑使用触发器立即转换和更新边列/表。

是否需要将其转换为xml?你不能简单地用patindex搜索nvarchar吗?你能展示一个xml结构的例子吗?每行典型的xml blob有多大?@JamieD77,不幸的是,xml包含大量的PII数据,但我可以说,它们看起来大约有3000-4000行长,在点中嵌套多达8层。@WillC看起来最小为22字节,最大为340MB,平均为6MB。我已经在搜索部分做了类似的工作,但这取决于它是否已经作为XML存储在SQL Server中。目前数据位于NVARCHAR字段中,问题是将该值转换为XML,以便我可以搜索它,而不是搜索本身。Ok。无法修改作为重要部分的现有表。是否尝试在转换的XmlData列上使用.value?找不到列XmlData或用户定义的函数或聚合XmlData.value,或者名称不明确。看起来.value在NVARCHAR数据上不起作用。是这样的吗?从历史记录中选择CONVERTXML、XMLData.value“/Updated/UserId[1]”、“int”作为UpdatedId
ALTER TABLE #tbl ADD RealXml XML;
GO
UPDATE #tbl SET RealXml=CAST(YourXMLasString AS XML);
SELECT * FROM #tbl;
CREATE TABLE #SideTable(RefID INT,RealXML XML);
INSERT INTO #SideTable
SELECT ID,CAST(YourXMLasString AS XML)
FROM #tbl;

SELECT * FROM #SideTable;