on 2016 Mar 15 12:01 PM
Can I use sa_split_list to split a row on first space nearest 20 character?
Ex:
This:
Test this row and try to split the row after 20 characters
Should be:
1.Test this row and
2.try to split the row
3.after 20 characters
Request clarification before answering.
Here's a sample using a stored procedure to split a string into according pieces and some test code. Note, it will only break at spaces, not other whitespace or punctuation (which might be useful), and it will leave longer "words" unchanged, so it does not guarantee that resulting lines are limited to 20 chars...
-- Some test data create table T_Test ( line_no int not null default autoincrement primary key, line long varchar not null ); insert T_Test (line) values ('Test this row and try to split the row after 20 characters'), ('ThisLongLineHas Three Spaces InIt.'), ('This.Long.Line.Has.No.Spaces.In.It,Which-Is-A-Pity.'), ('Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.'); -- split "str" at "delim" boundaries into lines with maximum "max_line_len" length create or replace procedure STP_LineBreaker(in str long varchar, in max_line_len int, in delim char(1) default ' ') result (line_no int, line long varchar) begin declare pos int; declare local temporary table LT_WrappedLine ( line_no int not null default autoincrement primary key, line long varchar not null ) not transactional; -- use locate with negative index (search from end) and use left with one more char than "max_line_len" -- (if you want at maximum 20 char, it's allright if the delim is at position 21) set pos = locate(left(str, max_line_len + 1), delim, -1); while len(str) > max_line_len and pos > 0 loop insert LT_WrappedLine (line) select substr(str, 1, pos - 1); set str = substr(str, pos + 1); set pos = locate(left(str, max_line_len + 1), delim, -1); end loop; -- insert the remaining part insert LT_WrappedLine (line) select str; select line_no, line from LT_WrappedLine order by 1; end; -- test call with your sample line (and dispalying the resulting lines's length): select *, len(line) from STP_LineBreaker('Test this row and try to split the row after 20 characters', 20); This returns: line_no,line,len(STP_LineBreaker.line) 1,Test this row and,17 2,try to split the row,20 3,after 20 characters,19 -- test call over the test table with the handy CROSS APPLY operator: select T_Test.line_no, sp.*, len(sp.line) from T_Test cross apply STP_LineBreaker(line, 20, ' ') sp order by 1, 2 This returns: line_no,line_no,line,len(sp.line) 1,1,Test this row and,17 1,2,try to split the row,20 1,3,after 20 characters,19 2,1,ThisLongLineHas,15 2,2,Three Spaces InIt.,18 3,1,This.Long.Line.Has.No.Spaces.In.It,Which-Is-A-Pity.,51 4,1,Lorem ipsum dolor,17 4,2,sit amet, consetetur,20 4,3,sadipscing elitr,,17 4,4,sed diam nonumy,15 4,5,eirmod tempor,13 4,6,invidunt ut labore,18 4,7,et dolore magna,15 4,8,aliquyam erat, sed,18 4,9,diam voluptua. At,17 4,10,vero eos et accusam,19 4,11,et justo duo dolores,20 4,12,et ea rebum.,12
As you can see, the original line 3 is not split into 20 chars or less as it has no spaces within. Also note that the "delim" character is omitted from the result. That may be allright with spaces but may not be adequate for other characters. But it shouldn't be too difficult to modify the procedure to add the "delim" to the result set - you would then choose "select substr(str, 1, pos);" but use left without the additional "+ 1" increment.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
82 | |
29 | |
9 | |
8 | |
7 | |
7 | |
7 | |
6 | |
6 | |
5 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.