更新:包含 XML 檔案的列的資料型別為文本。
更新 2(這幫助我使用 xml 函式而不是使用 charindex 來操作資料):我創建了一個臨時表 #tmpXML(id int,xmlField XML)。id 是我的主表的主鍵,xmlField 是文本型別欄位中的 XML 值。我在臨時表中的 XML 資料欄位上使用了 XML 函式,得到了我需要的所有值,并用這些值更新了我的主表。
我發現這種方法比使用 charindex 和 substring 等 sql server 函式更高效、更簡潔。這就是我接受答案的原因,因為它幫助我使用了 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但它變得太混亂了。關于如何做到這一點的任何想法?謝謝!
uj5u.com熱心網友回復:
您可以.modify()為此使用 XML 函式,使用replace value of語法
UPDATE users
SET Settings.modify('replace value of (owner/product/@region)[1] with "East"');
db<>小提琴
這僅適用于每行一個 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;
db<>小提琴
uj5u.com熱心網友回復:
您可以在 select Case When colName like '%NORTH%' 然后替換 (colName, NORTH, NEWTEXT When colName like '%SOUTH%' etc
您還可以創建一個存盤的功能
uj5u.com熱心網友回復:
請嘗試以下解決方案。
Text是 MS SQL Server 中不推薦使用的資料型別。我使用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;
uj5u.com熱心網友回復:
Try good old REPLACE ( string_expression , string_pattern , string_replacement ) in your SQL query
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/425872.html
上一篇:使用特定邏輯合并SQL中的行
