Re: [pgbr-geral] duvida com as aspas dentro de aspas ao criar função

2014-01-19 Por tôpico Eloi

 É, parece que você criou uma bagunça com as aspas mesmo... Acho que vai
 ficar mais fácil refazer a função do que ajustar cada problema nela. Já que
 vamos refazer, que tal adicionar algumas dicas de ouro? ;-)


 Bom, primeiro, veja o modelo que criei (não testei, então pode ter algum
 erro que eu não tenha visto):

 CREATE OR REPLACE FUNCTION wosis.fun_create_sequence(sch text)
 RETURNS text
 LANGUAGE plpgsql VOLATILE
 AS
 $BODY$
 DECLARE
 row record;
 BEGIN
 FOR row IN
 SELECT table_name, table_name||'_id' AS id_name, 0 AS next_value
 FROM information_schema.tables
 WHERE table_schema = sch
 AND  table_type = 'BASE TABLE'
 ORDER BY table_name
 LOOP
 EXECUTE
 format('SELECT max(%I)+1 FROM %I.%I', row.id_name, sch,
 row.table_name)
 INTO row.next_value;
 EXECUTE
 format(
 'CREATE SEQUENCE %I.%I START %L OWNED BY %I.%I.%I;',
 sch,
 row.table_name||'_'||row.id_name||'_seq',
row.next_value -- faltava
 sch,
 row.table_name,
 row.id_name
 );
EXECUTE
format(
 'ALTER TABLE %I.%I ALTER COLUMN %I SET DEFAULT
 nextval(%L);', -- AQUI FALTAVA A VIRGULA
 sch,
 row.table_name,
 row.id_name,
 row.table_name||'_'||row.id_name||'_seq'
 );
 END LOOP;
 RETURN 'Sequences were created';
 END;
 $BODY$;

 Agora vejamos... Em primeiro lugar eu não usei uma tabela temporário,
 simplesmente porque não vi sentido, e acho que acabou deixando a função
 mais confusa ainda. Ao invés disso eu apenas naveguei no resultado da
 consulta à view information_schema.tables. Repare também que não usei
 consulta dinâmica (comando EXECUTE) nesta consulta, simplesmente porque não
 é necessário e recomendo evitar o uso de EXECUTE ao máximo.

 Em segundo lugar, precisamos de três comandos, um para fazer um `SELECT
 max` para recuperar o maior valor, outro para criar a sequência e o último
 para alterar o DEFAULT da tabela. Em ambos os casos a função format ajuda
 bastante, e não precisa de tantos quote_ident's, que podem ser confusos.

 Em [1] há um comparativo legal entre format e quote_ident. Veja lá e poste
 dúvidas que sobrarem aqui.

 Por fim, adicionei a cláusula OWNED BY no CREATE SEQUENCE, para deixar
 idêntico ao que o pseudo-tipo SERIAL faz, e é uma boa prática para futuras
 manutenções.

 Só tenho mais um comentário. Esses comandos estão (talvez erroneamente)
 assumindo que toda tabela tem um campo nome da tabela_id, mas talvez
 faça parte do seu modelo, mas eu evitaria isso, a não ser que seja algo
 executado somente numa tarefa administrativa.

 Ufa... Leia com calma, tentei ser o mais claro possível. ^^

 [1]
 http://www.postgresql.org/docs/current/static/plpgsql-statements.html#PLPGSQL-QUOTE-LITERAL-EXAMPLE


 Atenciosamente,

Obrigado a todos pelas respostas e desculpar-me por não responder antes.

Gostei das dicas do 'format()', muito parecido ao python e também do
'INTO row.next_value', não conhecia. E sem duvida que conceptualmente a
função ficou muito melhor, não complicou. Parece que terei de rever
todas as minhas funções que estive a escrever na ultima semana.

Sim, todas as tabelas tem o nome da tabela_id, fiz uma função para
que assim fosse. E sim, é apenas uma tarefa administrativa num esquema
com 70 tabelas.

Foi necessário uns retoques minimos, uma virgula que falatva e passar o
valor de row.next_value.

Agora só falta um detalhe, esta a passar o valor de 'next_value' como
texto e salta erro. Tentei o 'cast' (::int) mas parece-me que isso é
apenas para o puro SQL.

ERROR:  syntax error at or near '25476'
LINE 1: ...E SEQUENCE wosis.class_fao_class_fao_id_seq START '25476' OW...
 ^
QUERY:  CREATE SEQUENCE wosis.class_fao_class_fao_id_seq START '25476'
OWNED BY wosis.class_fao.class_fao_id;
CONTEXT:  PL/pgSQL function fun_create_sequence line 19 at EXECUTE
statement

Como faço para passar o valor como inteiro?

Muito obrigado a todos pelas sugestões, correções e explicações.

Eloi



___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral


Re: [pgbr-geral] duvida com as aspas dentro de aspas ao criar função

2014-01-19 Por tôpico Rafael Fialho Corrêa

 Como faço para passar o valor como inteiro?


Segue exemplo retirado da documentação:

EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname)
USING newvalue, keyvalue;

Vide [1] 39.5.4. Executing Dynamic Commands em caso de dúvidas.
[]'s

[1]:
http://www.postgresql.org/docs/9.2/interactive/plpgsql-statements.html#PLPGSQL-QUOTE-LITERAL-EXAMPLE
___
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral