2013-06-12 37 views
5

Trong MS SQL Server 2012 tôi có một cơ sở dữ liệu với một bảng chứa một cột VARCHAR chứa một số văn bản mà thậm chí có thể bao gồm ngắt dòng.Lấy số dòng cho varchar cụ thể trong MS SQL

dụ cơ bản:

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'); 

Bây giờ tôi muốn nhận được tổng số dòng văn bản cho mỗi bản ghi, tức là một cái gì đó như thế này:

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

Thật không may, dường như không có một hàm tích hợp cho một cái gì đó như thế này. Ý tưởng của tôi là đếm số Chr(10)+Chr(13) lần xuất hiện và thêm 1 vào cuối. Nhưng CHARINDEX chỉ tìm thấy lần xuất hiện đầu tiên trong chuỗi.

Bất kỳ ý tưởng nào về cách giải quyết vấn đề này?

Thông tin bổ sung có thể hữu ích: Để cung cấp thông tin chi tiết hơn về dữ liệu của tôi, "Văn bản" đến từ chuỗi XML có ngắt dòng, ví dụ:

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

tôi sử dụng CROSS APPLY XML.nodes(... và XPath để tìm tất cả <a> nút trong XML. Điều này có thể được giải quyết trực tiếp với các hàm XML của T-SQL không?

+0

Cảm ơn, đã thay đổi nó. Tôi đã sao chép nó từ sqlfiddle.com nhưng không biết tôi đang ở chế độ MySQL – Markus

Trả lời

7

Sử dụng Replace để loại bỏ ngắt dòng thông qua thay thế bằng không có gì (''). Sau đó, bạn có thể trừ đi các lengh của văn bản sửa đổi từ bản gốc.

+0

+1 cho câu trả lời hay. – Devart

+0

Cảm ơn, điều này dường như hoạt động tốt! – Markus

+0

Làm cách nào để đếm các dòng không trống? – BlueChippy

4

Hãy thử điều này:

select id, text,LEN(Text)-LEN(replace(text,char(10),''))+1 LinesOfText 
from Example 
+0

@Markus: Điều này có hữu ích không? –

+1

+1 để có câu trả lời hay. – Devart

+3

Cảm ơn câu trả lời và ví dụ của bạn! Làm việc tốt! – Markus

6

Hãy thử này -

Query:

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 

Output:

id     LinesOfText 
-------------------- -------------------- 
1     1 
2     3 
3     2 
+0

Cảm ơn sự giúp đỡ của bạn, LEN() và REPLACE() là những gì tôi cần. – Markus

+0

Bạn được chào đón @Markus. – Devart

2

Không có gì thông minh về cách tiếp cận này, và tôi nghĩ rằng các ví dụ sử dụng thay thế là tao nhã hơn, nhưng điều này là khá đai và niềng răng:

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 @[email protected]+1 
     SET @LastOffset=CHARINDEX(CHAR(10) ,@Text, @LastOffset+1) 
    END 

    Return @Result 
End 
+1

Cảm ơn bạn đã cho thấy cách triển khai phương pháp tiếp cận đầu tiên của tôi, điều này cũng có thể hữu ích cho những người khác muốn viết chức năng của riêng họ. – Markus

Các vấn đề liên quan