Обсуждение: How to implement word wrap
Database column contains large string without line feeds.
How to split it with word wrap between words ?
I tried to implement word wrap using
create temp table test (line char(7));
insert into test select repeat('aa ',10);
select * from test;
Expected result is that table test contains multiple rows and every row
contains two words:
aa aa
Instead I got string too long exception.
How to implement word wrap in PostgreSql if string contains words of any
size separated by spaces?
Andrus.
2010/3/29 Andrus <kobruleht2@hot.ee>
Database column contains large string without line feeds.
How to split it with word wrap between words ?
I tried to implement word wrap using
create temp table test (line char(7));
insert into test select repeat('aa ',10);
select * from test;
Expected result is that table test contains multiple rows and every row contains two words:
aa aa
Instead I got string too long exception.
How to implement word wrap in PostgreSql if string contains words of any size separated by spaces?
Andrus.
--
No, what you've done is asked it to insert 'aa aa aa aa aa aa aa aa aa aa'.
I suspect you're looking for:
INSERT INTO test SELECT 'aa' FROM generate_series(1,10);
Regards
Thom
Andrus <kobruleht2@hot.ee> wrote:
> Database column contains large string without line feeds.
> How to split it with word wrap between words ?
> I tried to implement word wrap using
>
> create temp table test (line char(7));
> insert into test select repeat('aa ',10);
> select * from test;
>
> Expected result is that table test contains multiple rows and every row
> contains two words:
>
> aa aa
>
> Instead I got string too long exception.
>
> How to implement word wrap in PostgreSql if string contains words of any
> size separated by spaces?
I think you have to write a function (plpgsql, plperl, ...), counting
chars per line and change space to newline if no more space in the line.
That's not really a SQL-problem ...
Maybe there are some perl-modules for that available, i don't know.
Andreas
--
Really, I'm not out to destroy Microsoft. That will just be a completely
unintentional side effect. (Linus Torvalds)
"If I was god, I would recompile penguin with --enable-fly." (unknown)
Kaufbach, Saxony, Germany, Europe. N 51.05082°, E 13.56889°
On 29 March 2010 17:42, Thom Brown <thombrown@gmail.com> wrote:
2010/3/29 Andrus <kobruleht2@hot.ee>Database column contains large string without line feeds.
How to split it with word wrap between words ?
I tried to implement word wrap using
create temp table test (line char(7));
insert into test select repeat('aa ',10);
select * from test;
Expected result is that table test contains multiple rows and every row contains two words:
aa aa
Instead I got string too long exception.
How to implement word wrap in PostgreSql if string contains words of any size separated by spaces?
Andrus.
--
No, what you've done is asked it to insert 'aa aa aa aa aa aa aa aa aa aa'.
I suspect you're looking for:
INSERT INTO test SELECT 'aa' FROM generate_series(1,10);
Regards
Thom
Just realised that's not what you're after, but my first point still stands.
Thom
> Just realised that's not what you're after, but my first point still
> stands.
Thank you.
I tried to wrap words at 15 characters using code below.
Issues:
1. Table rows places same word to multiple lines. How to remove them so that
every word appears only in single row?
2. In last select sum(word||' ') causes error. How to concatenate words
bact to row (inverse of unnest() function ?
Andrus.
create temp table words( id serial, word text ) on commit drop;
insert into words (word) select * from unnest(string_to_array('Quick brown
fox runs in forest.',' '));
create temp table results on commit drop as
select
first.id as first,
last.id as last,
sum(length(a.word)+1) as charcount
from words a, words first, words last
where a.id between first.id and last.id
group by 1,2
having sum(length(a.word)+1)<15;
create temp table maxr on commit drop as
select
first,
max(charcount) as charcount
from results
group by 1;
create temp table rows on commit drop as
select
first,
last
from results
join maxr using (first,charcount)
order by 1;
select
rows.first,
sum(word||' ')
from rows, words
where words.id between first and last
group by 1
order by 1, words.id
On 30 Mar 2010, at 11:32, Andrus wrote: >> Just realised that's not what you're after, but my first point still stands. > > Thank you. > I tried to wrap words at 15 characters using code below. Really, write a stored procedure that accepts (text, line_length) and returns SETOF text. You could even add hyphenationfor the appropriate language if you go that route. For the latter it's probably best to write it in C so you canlink hyphenation libraries to your code. Another approach that may be viable is to use windowing functions, but I'm not so sure it's possible to have a window thatis being defined by the data it's running over (eg. a window defined by the length of an accumulated line of text). Alban Hertroys -- Screwing up is an excellent way to attach something to the ceiling. !DSPAM:737,4bb1d23410411798520618!
> Really, write a stored procedure that accepts (text, line_length) and > returns SETOF text. You could even add hyphenation for the appropriate > language if you go that route. For the latter it's probably best to write > it in C so you can link hyphenation libraries to your code. > > Another approach that may be viable is to use windowing functions, but I'm > not so sure it's possible to have a window that is being defined by the > data it's running over (eg. a window defined by the length of an > accumulated line of text). Implementations from http://sqlserverpedia.com/wiki/Word_Wrap_a_String and from http://docstore.mik.ua/orelly/oracle/prog2/ch11_02.htm#AUTOID-10508 paragraph 11.2.2 did not work in Postgres. I created method below. Is this best code for this ? Andrus. CREATE OR REPLACE FUNCTION wordwrap(line text, linelen integer) RETURNS SETOF text as $$ DECLARE words text[] := string_to_array(line,' '); i integer; res text:=''; BEGIN if trim(line)='' then return next ''; return; end if; for i IN 1 .. array_upper(words,1) LOOP if length(res)+length(words[i]) > linelen THEN return next res; res := ''; END IF ; if res<>'' then res := res || ' '; end if; res := res || words[i]; end loop; return next res; END $$ LANGUAGE plpgsql;