2009-12-31 119 views
16

Estoy buscando una función como regexp_split_to_table, pero nuestra db es la versión 8.2.9, por lo que no la tiene. Estoy realmente única división en un espacio, por lo que una cadena comosql dividir cadena por espacio en la tabla en postgresql

how now brown cow

volvería

+------+ 
|Column| 
+------+ 
|how | 
|now | 
|brown | 
|cow | 
+------+ 

hay una función simple que puede manejar esto, o algo que tengo que escribir yo mismo?

Respuesta

34

Puede dividir una matriz en un conjunto de resultados utilizando la función unnest, y puede convertir una cadena literal en una matriz utilizando la función string_to_array. Combinar los dos y se obtiene lo siguiente:

alvherre=# select unnest(string_to_array('the quick lazy fox', ' ')); 
unnest 
-------- 
the 
quick 
lazy 
fox 
(4 filas) 

Desde 8.2 no tiene UNNEST, puede escribirlo en PostgreSQL así:

create or replace function unnest(anyarray) returns setof anyelement 
language sql as $$ 
    select $1[i] from generate_series(array_lower($1, 1), 
            array_upper($1, 1)) as i; 
$$; 
+0

+1 para * generate_series * y * unnest *. – pilcrow

2

Creo que tendrá que RETURNS SET o RETURNS TABLE usted mismo.

respuesta Actualizado: utilizando PL/pgSQL:

pg=> CREATE OR REPLACE FUNCTION string_to_rows(text) RETURNS SETOF TEXT AS $$ 
    DECLARE 
    elems text[];  
    BEGIN 
    elems := string_to_array($1, ' '); 
    FOR i IN array_lower(elems, 1) .. array_upper(elems, 1) LOOP 
     RETURN NEXT elems[i]; 
    END LOOP; 
    RETURN; 
    END 
$$ LANGUAGE 'plpgsql'; 
CREATE FUNCTION 

pg=> SELECT "Column" FROM string_to_rows('how now brown cow') d("Column"); 
Column 
-------- 
how 
now 
brown 
cow 
(4 rows) 

Respuesta original: utilizando PL/Perl:

pg=> CREATE LANGUAGE plperl; 
CREATE LANGUAGE 

pg=> CREATE FUNCTION psplit_to_rows(text) RETURNS SETOF TEXT AS $$ 
pg$> for my $t (split ' ', $_[0]) { return_next $t; } 
pg$> undef; 
pg$> $$ LANGUAGE plperl; 
CREATE FUNCTION 

pg=> SELECT "Column" FROM psplit_to_rows('how now brown cow') d("Column"); 
Column 
-------- 
how 
now 
brown 
cow 
(4 rows) 

Obviamente se puede extender esto a manejar un delimitador de su elección , etc. (Nota, no estoy seguro de si realmente deseaba esa columna llamada "Columna", que requiere el uso de un identificador para evitar el choque de palabras clave, pero, ahí está).

+0

no tengo plperl para trabajar, puede esto ser fácilmente hecho w/plpgsql? – veilig

+0

@veilig, sí, actualizado. – pilcrow

+0

@pilcrow, Tu función funciona muy bien, pero tengo un problema cuando trato de ejecutar una consulta como [select string_to_rows (column) from table]. Me sigue dando el error: ERROR: función de valor de conjunto llamado en contexto que no puede aceptar un conjunto. Mirando en línea, veo que necesito llamar como [seleccionar * de string_to_rows (texto)]. ¿Es posible llamar a esta función y pasarla en un conjunto? es decir [select * from string_to_rows (seleccione col de la tabla)]. – veilig

Cuestiones relacionadas