减少文本字段中的文本

时间:2011-03-04 16:06:24

标签: sql-server-2005

我正在研究一个从另一个表中选择一个大文本字段的视图。 (不,不是快照。)此表包含来自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;或者其他什么。
有可能吗?

2 个答案:

答案 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,其中包含您所指的大文本。

  1. 创建一个将文本内容拆分为单词的特殊函数(从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
    
  2. 然后使用下面的查询从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 (''))
        ,'&amp;','&')
        ,'&lt;','<')
        ,'&gt;','>')
        ,'&#x0A;',char(10))
        ,'&#x0D;',char(13))
        ,'&#x09',char(9))
     )
    AS Details 
    FROM ErrorLog
    
  3. 请注意,我使用50作为阈值,否则它也会剪切像'System.Web.HttpException'这样长度为&gt;的项目。 20。