我的nvarchar(max)
类型列。
它有html文本作为字符串。像吼叫一样。
<a>hi_this </a>
<i>is_sample</i>
<p>text_data</P>
<a>in_column</a>
<p>this_is_paragraph</p>
<a>this_is_end</a>
无论如何,顶部替换标记_
和<p>
之间的下划线(</p>
)符号
所以我希望最终输出像下面一样。
<a>hi_this </a>
<i>is_sample</i>
<p>text data</P>
<a>in_column</a>
<p>this is paragraph</p>
<a>this_is_end</a>
有可能吗?
更新的 它是这样的单排。 &#39;&LT; a&gt; hi_this&lt; / a&gt;&lt; i&gt; is_sample&lt; / i&gt;&lt; p>文本数据&lt; / P&gt;&lt; a&gt; in_column&lt; / a&gt; &LT; p>这是段落&lt; / p&gt; &LT; a&gt; this_is_end&lt; / a&gt;&#39;
答案 0 :(得分:2)
为什么不使用简单的REPLACE功能
update my_table
set path = replace(path, '_', ' ')
WHERE path like '<p>%'
答案 1 :(得分:2)
我真的不认为SQL是最好的工具,但我做了一些似乎适用于你的情况。第一步是建立一个数字表。如果你已经拥有了那么好,请使用它,但为了得到一个完整的答案,我认为你没有。
只需使用table value constructor创建一个包含10行(N1
)的表格,然后将其与自身交叉连接以获得100行(N3
),然后交叉即可完成此操作将其与自身连接以获得10,000行(Numbers
)的表格,然后使用ROW_NUMBER()
获取每行1-10,000的数字:
WITH N1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
Numbers (Number) AS (SELECT ROW_NUMBER() OVER(ORDER BY N1.N) FROM N2 AS N1 CROSS JOIN N2 AS N2)
SELECT *
FROM Numbers;
可以在Generate a set or sequence without loops系列中找到关于此问题的进一步阅读以及其他这样做的方法。如果您需要超过10,000个数字,只需添加更多交叉连接,直到您有足够的
获得数字表后,您可以使用SUBSTRING()
来确定所有开放<p>
代码的位置,使用“
DECLARE @S NVARCHAR(500) = '
<a>hi_this </a>
<i>is_sample</i>
<p>text_data</P>
<a>in_column</a>
<p>this_is_paragraph</p>
<a>this_is_end</a>';
WITH N1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
Numbers (Number) AS (SELECT ROW_NUMBER() OVER(ORDER BY N1.N) FROM N2 AS N1 CROSS JOIN N2 AS N2)
SELECT OriginalString = SUBSTRING(@S, Number, CHARINDEX('</p>', @s, Number + 1) - Number + 4),
Start = Number,
NumChars = CHARINDEX('</p>', @s, Number + 1) - Number + 4,
NewString = REPLACE(SUBSTRING(@S, Number, CHARINDEX('</p>', @s, Number + 1) - Number + 4), '_', ' ')
FROM Numbers
WHERE SUBSTRING(@S, Number, 3) = '<p>';
结果:
OriginalString Start NumChars NewString
---------------------------------------------------------------------------
<p>text_data</P> 40 16 <p>text data</P>
<p>this_is_paragraph</p> 80 24 <p>this is paragraph</p>
您可以使用SUBSTRING(@S, Number, 3) = '<p>'
获取每个p
代码的起始位置,然后使用CHARINDEX()
获取下一个结束p
代码的位置,以及替换之间的文本。
最后,您需要使用此输出替换原始字符串,您可以使用STUFF()
执行此操作:
DECLARE @S NVARCHAR(500) = '
<a>hi_this </a>
<i>is_sample</i>
<p>text_data</P>
<a>in_column</a>
<p>this_is_paragraph</p>
<a>this_is_end</a>';
WITH N1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
Numbers (Number) AS (SELECT ROW_NUMBER() OVER(ORDER BY N1.N) FROM N2 AS N1 CROSS JOIN N2 AS N2),
Data AS
( SELECT OriginalString = SUBSTRING(@S, Number, CHARINDEX('</p>', @s, Number + 1) - Number + 4),
Start = Number,
NumChars = CHARINDEX('</p>', @s, Number + 1) - Number + 4,
NewString = REPLACE(SUBSTRING(@S, Number, CHARINDEX('</p>', @s, Number + 1) - Number + 4), '_', ' ')
FROM Numbers
WHERE SUBSTRING(@S, Number, 3) = '<p>'
)
SELECT @S = STUFF(@S, Start, NumChars, NewString)
FROM Data;
PRINT @S;
给出了:
<a>hi_this </a>
<i>is_sample</i>
<p>text data</P>
<a>in_column</a>
<p>this is paragraph</p>
<a>this_is_end</a>
答案 2 :(得分:0)
您可以在REPLACE
中使用CASE
:
SELECT CASE
WHEN col LIKE '<p>%' AND col LIKE '%</p>' THEN REPLACE(col, '_', ' ')
ELSE col
END AS col
FROM #table1
<强>输出强>
<a>hi_this </a>
<i>is_sample</i>
<p>text data</P>
<a>in_column</a>
<p>this is paragraph</p>
<a>this_is_end</a>
<强>更新强>
如您所愿,这会将结果集合并为1行:
DECLARE @combine VARCHAR(MAX)
;WITH cte AS (
SELECT CASE WHEN col LIKE '<p>%' and col LIKE '%</p>' THEN REPLACE(col, '_', ' ') ELSE col END AS col
FROM table1
)
SELECT @combine = COALESCE(@combine, ' ') + col
FROM cte
SELECT @combine as col
<强>输出强>
<a>hi_this </a><i>is_sample</i><p>text data</P><a>in_column</a><p>this is paragraph</p><a>this_is_end</a>
<强> SQL FIDDLE 强>