6

在 MS SQL Server 2012 中,我有一个数据库,其中包含一个包含 varchar 列的表,该列包含一些甚至可能包含换行符的文本。

基本示例:

CREATE TABLE Example
(
    [ID] INT
  , [Text] VARCHAR(100)
);

INSERT INTO Example ([ID], [Text])
VALUES
        (1, 'This is a test'),
        (2, 'This is another
         test with
         two line breaks'),
        (3, 'This is a test
         with one line break');

现在我想获得每条记录的总文本行数,即这样的:

--------------------
| ID | LinesOfText |
--------------------
|  1 |           1 |
--------------------
|  2 |           3 |
--------------------
|  3 |           2 |
--------------------

不幸的是,似乎没有这样的内置函数。我的想法是计算Chr(10)+Chr(13)出现次数并在最后添加 1。但CHARINDEX只找到字符串中的第一次出现。

知道如何解决这个问题吗?

可能有用的额外信息:为了更深入地了解我的数据,“文本”来自包含换行符的 XML 字符串,例如

...
<a>This is
   another test
   with two line breaks</a>
... 

我使用CROSS APPLY XML.nodes(...XPath 来查找<a>XML 中的所有节点。这可以用 T-SQL XML 函数直接解决吗?

4

4 回答 4

8

用于Replace通过无替换 ( ) 来消除换行符''。然后您可以从原始文本中减去修改后的文本的长度。

于 2013-06-12T11:01:40.850 回答
8

尝试这个 :

select id, text,LEN(Text)-LEN(replace(text,char(10),''))+1 LinesOfText
from Example 
于 2013-06-12T11:21:18.307 回答
7

试试这个——

询问:

DECLARE @XML XML
SELECT @XML = '<p>
<a>This is a test</a>
<a>This is
     another test
     with two line breaks</a>
<a>This is a test
     with one line break</a>
</p>'

SELECT 
      id = ROW_NUMBER() OVER (ORDER BY (SELECT 1))
    , LinesOfText = LEN(txt) - LEN(REPLACE(txt, CHAR(10), '')) + 1
FROM (
    SELECT txt = t.c.value('.', 'VARCHAR(MAX)')
    FROM @XML.nodes('p/a') t(c)
) t

输出:

id                   LinesOfText
-------------------- --------------------
1                    1
2                    3
3                    2
于 2013-06-12T11:40:58.580 回答
4

这种方法没什么聪明的,我认为使用 replace 的示例更优雅,但这是相当带和大括号的:

CREATE FUNCTION dbo.fn_LinesOfText(@Text varchar(MAX)) Returns INT As
Begin
    Declare @Result int, @LastOffset int

    SET @LastOffset=0
    SET @Result=1   
    SET @LastOffset=CHARINDEX(CHAR(10), @Text, @LastOffset)
    WHILE @LastOffset>=1 BEGIN
        SET @Result=@Result+1
        SET @LastOffset=CHARINDEX(CHAR(10) ,@Text,  @LastOffset+1)
    END

    Return @Result
End
于 2013-06-12T11:47:17.350 回答