我正在研究一个从另一个表中选择一个大文本字段的视图。 (不,不是快照。)此表包含来自Web应用程序的错误日志,该日志提供对它的访问。但是,此错误日志包含一些非常长的文本,这些文本会导致列非常宽 所以我想选择文本字段,但任何超过20个字符的字必须替换为前三个字符,椭圆(...)和最后三个字母。例如:
- System.Web.HttpException: The client
disconnected. --->
System.Web.UI.ViewStateException:
Invalid viewstate. Client IP:
xxx.xxx.xxx.xxx Port: xxxx
User-Agent: Mozilla/4.0 (compatible;
MSIE 7.0; Windows NT 6.1; WOW64;
Trident/4.0; SLCC2; .NET CLR
2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; InfoPath.3; .NET4.0C;
.NET4.0E) ViewState:
T89RiGYTOALETOKughad85KzoDRo/ut3Vlnd1qECsYf1t9GGNilDrvbRn8l45SVX8AsZrs6zyEngk8MKdpoRecI4j0X5IsmI0Deldf4nLKNlLoE4xaOoMUlj7hTFRXAvqyOFSvzsvyhwpWCLuG26RJT4YbGr1IJYgqWX9KVplIdasDUR0aNNMvD9FVa8Fi33Ny7fuIjxPKMpqKByKYJtAgZU4PIji88MMQWQDMNZmBxM965+bN+RsvTSxrGWzLLhzFCrK0LeCCrZeRQyncmMhUPGM9YB1+UapRfeca3R4vCacN6vv/UnZekBXP5rzAvDgJB9RGgXKhhdBVeCCD3h2N6X5RxKKLdy76h3AVZ8H8DfJpdjvre8ExNdkHeCOZWz0EjyX9hNMe2KZ2+gmEQaFi/mNJ5nZzCjOCfYsdbwAorpEGBZNqX9gBjDs32e8Admgdk+zvxl3Mt4pF3e6zTh45N1cCjBNCLya6Rd9d9mfiPM6DFbXUBiXw8dbZmT/6veCw0YPfRCjKCod3D7+Kva44RuiIkKIIqr0vPLLlja/ggH/4iHq9SqgOpwGJuoHGfy++5G14bIv3Zyzm8Vj+re3iMfbwZCUI4sCeFy7L7I6NrL27pd+6Qz60WAMv6lPl3Y88J5CUIVAIZqINsOt5htisTf00+d0pFptx5wwlmprzm1dVfXcL/0x3BPvlNDof5aW+PJxAP19SHR+PUuAEm9YO0ZmhGg+L5+DN2kuHSpQFpwC6FxCzVdicxlR8+x4jUy2+Fxeblabla
这必须成为:
- System.Web.HttpException: The client
disconnected. --->
System.Web.UI.ViewStateException:
Invalid viewstate. Client IP:
xxx.xxx.xxx.xxx Port: xxxx
User-Agent: Mozilla/4.0 (compatible;
MSIE 7.0; Windows NT 6.1; WOW64;
Trident/4.0; SLCC2; .NET CLR
2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; InfoPath.3; .NET4.0C;
.NET4.0E) ViewState: T89...bla
是的,第一个文字非常宽......即使SO也无法正确显示它。 :-)
所以,我可能需要用正则表达式做些什么。因此:SELECT REGEX(Something,something,something)FROM MyTable;或者其他什么。
有可能吗?
答案 0 :(得分:2)
也许这会有所帮助
CREATE FUNCTION dbo.EllipseTextWords(@Text VARCHAR(MAX), @EllipsedSize INT, @Separator AS VARCHAR(1), @EllipsisLength INT = 3)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @Tokens TABLE
(
Token VARCHAR(MAX)
)
WHILE (CHARINDEX(@Separator, @Text) > 0)
BEGIN
INSERT INTO @Tokens
SELECT LTRIM(RTRIM(SUBSTRING(@Text, 1, CHARINDEX(@Separator, @Text) - 1)))
SET @Text = SUBSTRING(@Text, CHARINDEX(@Separator, @Text) + 1, LEN(@Text))
END
INSERT INTO @Tokens
SELECT LTRIM(RTRIM(@Text))
UPDATE @Tokens SET Token = LEFT(Token, @EllipsisLength) + '...' + RIGHT(Token, @EllipsisLength) WHERE Token <> '' AND LEN(Token) > LEN(LEFT(Token, @EllipsedSize))
DECLARE @Ellipsed VARCHAR(MAX)
SELECT @Ellipsed = COALESCE(@Ellipsed + @Separator, '') + Token FROM @Tokens
RETURN @Ellipsed
END
然后你可以调用创建的函数
SELECT dbo.EllipseTextWords(Details, 20, ' ', DEFAULT) FROM ErrorLog
但我想知道为什么不在表示层中这样做。
答案 1 :(得分:1)
以下解决方案如何?假设您的包含错误日志的表名为ErrorLog
,并且有一列Details
,其中包含您所指的大文本。
创建一个将文本内容拆分为单词的特殊函数(从here获取,但基本上任何类似的函数都可以使用):
CREATE FUNCTION dbo.Split(@String varchar(8000), @Delimiter char(1))
returns @temptable TABLE (items varchar(8000))
as
begin
declare @idx int
declare @slice varchar(8000)
select @idx = 1
if len(@String) < 1 or @String is null return
while @idx != 0
begin
set @idx = charindex(@Delimiter, @String)
if @idx != 0
set @slice = left(@String, @idx - 1)
else
set @slice = @String
if(len(@slice) > 0)
insert into @temptable(Items) values(@slice)
set @String = right(@String, len(@String) - @idx)
if len(@String) = 0 break
end
return
end
然后使用下面的查询从ErrorLog表中检索文本字段(基本上,它遍历所有单词,检查每个项目的长度,然后将它们连接成一个新字符串):
SELECT
(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
(SELECT (CASE WHEN LEN(items) > 50
THEN LEFT(items, 3) + '...' + RIGHT(items, 3)
ELSE items
END) + ' '
FROM dbo.Split(ErrorLog.Details, ' ') FOR XML PATH (''))
,'&','&')
,'<','<')
,'>','>')
,'
',char(10))
,'
',char(13))
,'	',char(9))
)
AS Details
FROM ErrorLog
请注意,我使用50作为阈值,否则它也会剪切像'System.Web.HttpException'这样长度为&gt;的项目。 20。