Sat*_*ish 1 sql sql-server sql-server-2012
我正在尝试使用下面的SQL 将HTML & "等名称转换为等效CHAR值.我在SQL Server 2012中测试了这个.
测试1(这很好):
GO
DECLARE @inputString VARCHAR(MAX)= '&testString&'
DECLARE @codePos INT, @codeEncoded VARCHAR(7), @startIndex INT, @resultString varchar(max)
SET @resultString = LTRIM(RTRIM(@inputString))
SELECT @startIndex = PATINDEX('%&%', @resultString)
WHILE @startIndex > 0
BEGIN
SELECT @resultString = REPLACE(@resultString, '&', '&'), @startIndex=PATINDEX('%&%', @resultString)
END
PRINT @resultString
Go
Run Code Online (Sandbox Code Playgroud)
输出:
&testString&
Run Code Online (Sandbox Code Playgroud)
测试2(这不起作用):由于上述工作,我试图扩展它以处理更多字符如下:
DECLARE @htmlNames TABLE (ID INT IDENTITY(1,1), asciiDecimal INT, htmlName varchar(50))
INSERT INTO @htmlNames
VALUES (34,'"'),(38,'&'),(60,'<'),(62,'>'),(160,' '),(161,'¡'),(162,'¢')
-- I would load the full list of HTML names into this TABLE varaible, but removed for testing purposes
DECLARE @inputString VARCHAR(MAX)= '&testString&'
DECLARE @count INT = 0
DECLARE @id INT = 1
DECLARE @charCode INT, @htmlName VARCHAR(30)
DECLARE @codePos INT, @codeEncoded VARCHAR(7), @startIndex INT
, @resultString varchar(max)
SELECT @count=COUNT(*) FROM @htmlNames
WHILE @id <=@count
BEGIN
SELECT @charCode = asciiDecimal, @htmlname = htmlName
FROM @htmlNames
WHERE ID = @id
SET @resultString = LTRIM(RTRIM(@inputString))
SELECT @startIndex = PATINDEX('%' + @htmlName + '%', @resultString)
While @startIndex > 0
BEGIN
--PRINT @resultString + '|' + @htmlName + '|' + NCHAR(@charCode)
SELECT @resultString = REPLACE(@resultString, @htmlName, NCHAR(@charCode))
SET @startIndex=PATINDEX('%' + @htmlName + '%', @resultString)
END
SET @id=@id + 1
END
PRINT @resultString
GO
Run Code Online (Sandbox Code Playgroud)
输出:
&testString&
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚我哪里出错了?任何帮助将非常感激.
我不想将字符串值加载到应用程序层,然后应用HTMLDecode并保存回数据库.
编辑:这条线SET @resultString = LTRIM(RTRIM(@inputString))在里面,WHILE所以我覆盖了结果@inputString.谢谢你,YanireRomero.
我也喜欢@ RichardDeeming的解决方案,但在这种情况下它不符合我的需求.
Ric*_*ing 16
这是一个不需要循环的简单解决方案:
DECLARE @htmlNames TABLE
(
ID INT IDENTITY(1,1),
asciiDecimal INT,
htmlName varchar(50)
);
INSERT INTO @htmlNames
VALUES
(34,'"'),
(38,'&'),
(60,'<'),
(62,'>'),
(160,' '),
(161,'¡'),
(162,'¢')
;
DECLARE @inputString varchar(max)= '&test&quot;<String>"&';
DECLARE @resultString varchar(max) = @inputString;
-- Simple HTML-decode:
SELECT
@resultString = Replace(@resultString COLLATE Latin1_General_CS_AS, htmlName, NCHAR(asciiDecimal))
FROM
@htmlNames
;
SELECT @resultString;
-- Output: &test"<String>"&
-- Multiple HTML-decode:
SET @resultString = @inputString;
DECLARE @temp varchar(max) = '';
WHILE @resultString != @temp
BEGIN
SET @temp = @resultString;
SELECT
@resultString = Replace(@resultString COLLATE Latin1_General_CS_AS, htmlName, NCHAR(asciiDecimal))
FROM
@htmlNames
;
END;
SELECT @resultString;
-- Output: &test"<String>"&
Run Code Online (Sandbox Code Playgroud)
编辑:NCHAR根据@tomasofen的建议更改为,并根据@TechyGypo的建议为函数添加了区分大小写的排序REPLACE规则.
出于性能考虑,这不应该作为T-SQL语句或SQL标量值函数编写..NET库提供了出色,快速,最重要的可靠 HTML解码.在我看来,你应该将它实现为SQL CLR,如下所示:
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.Net;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction(
IsDeterministic = true,
IsPrecise = true,
DataAccess = DataAccessKind.None,
SystemDataAccess = SystemDataAccessKind.None)]
[return: SqlFacet(MaxSize = 4000)]
public static SqlString cfnHtmlDecode([SqlFacet(MaxSize = 4000)] SqlString input)
{
if (input.IsNull)
return null;
return System.Net.WebUtility.HtmlDecode(input.Value);
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的T-SQL中,像这样调用它:
SELECT clr_schema.cfnHtmlDecode(column_name) FROM table_schema.table_name
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12004 次 |
| 最近记录: |