[英]How can I query a value in SQL Server TEXT column that contains XML (not xml column type)
[英]Find a string with in a TEXT type column that contains an XML file and replace a value in SQL Server
更新:包含 XML 文件的列的数据类型为文本。
更新 2(这帮助我使用 xml 函数而不是使用 charindex 来操作数据):我创建了一个临时表#tmpXML(id int,xmlField XML)。 id 是我的主表的主键,xmlField 是文本类型字段中的 XML 值。 我在临时表的 XML 数据字段上使用了 XML 函数,得到了我需要的所有值,并用这些值更新了我的主表。
我发现这种方法比使用 sql 服务器函数(如 charindex 和 substring)更有效和干净。这就是我接受答案的原因,因为它帮助我使用 xml 函数。 只是想澄清一下。
我有一个名为Settings
的列,其中包含带有用户设置的 xml 文件。
例如,我有 3 个用户具有此列的以下列。
第一个用户 ID 1 为 XML:
<owner>
<product userid="1" productid="3" region="North" country="Usa" ></product>
</owner>
第一个用户 ID 2 为 XML:
<owner>
<product userid="2" productid="3" selectedView="true" region="North" state="AZ" country="Usa" ></product>
</owner>
第一个用户 ID 3 为 XML:
<owner>
<product userid="3" productid="3" selectedView="true" region="South" isSelected="true" state="AZ" country="Usa" ></product>
</owner>
如您所见,每个用户的属性在 XML 文件中可以按任何顺序排列。 我必须更新所有用户以拥有 region = "East"。 我尝试使用CharIndex
和substring
,但它变得太混乱了。 关于如何做到这一点的任何想法? 谢谢!
您可以使用.modify()
XML function 为此,使用语法的replace value of
UPDATE users
SET Settings.modify('replace value of (owner/product/@region)[1] with "East"');
这仅适用于每行一个 XML 文档。
如果您实际上将所有这些节点都放在一个大块中,则需要循环运行它
DECLARE @tries int = 0;
WHILE @@ROWCOUNT > 0 AND @tries < 1000
BEGIN
UPDATE users
SET Settings.modify('replace value of (owner/product/@region[. != "East"])[1] with "East"')
WHERE Settings.exist('owner/product/@region[. != "East"]') = 1;
SET @tries += 1;
END;
在您的 SQL 查询中尝试好的旧 REPLACE ( string_expression, string_pattern, string_replacement )
您可以在 select 案例中使用 case 语句当 colName like '%NORTH%' 然后替换 (colName, NORTH, NEWTEXT When colName like '%SOUTH%' etc
您还可以创建一个存储的 function
请尝试以下解决方案。
Text
是 MS SQL 服务器中已弃用的数据类型。 我使用NVARCHAR(MAX)
数据类型将其与 XML 数据的自然 XML 数据类型区分开来。
SQL
DECLARE @tbl TABLE (id int primary key, Settings NVARCHAR(MAX));
INSERT @tbl VALUES
(1,'<owner>
<product userid="1" productid="3" region="North" country="Usa" ></product>
</owner>'),
(2,'<owner>
<product userid="2" productid="3" selectedView="true" region="North" state="AZ" country="Usa" ></product>
</owner>'),
(3,'<owner>
<product userid="3" productid="3" selectedView="true" region="South" isSelected="true" state="AZ" country="Usa" ></product>
</owner>');
WITH rs AS
(
SELECT *
FROM @tbl
CROSS APPLY (SELECT TRY_CAST(Settings AS XML)
.query('<owner><product>
{
for $x in /owner/product/@*
return if(local-name($x) ne "region") then $x
else attribute region {"East"}
}
</product></owner>')) t(x)
)
UPDATE rs
SET rs.Settings = TRY_CAST(x AS NVARCHAR(MAX));
-- test
SELECT * FROM @tbl;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.