Estou tentando criar uma UDF que crie um recurso de cláusula VIEW
dinamicamente usando o USING
recurso. O problema é que EXECUTE
não aceitará o parâmetro passado no CREATE VIEW
comando.
CREATE OR replace FUNCTION test(name varchar) RETURNS void LANGUAGE plpgsql AS $$
BEGIN
EXECUTE format('create or replace view %I as select $1 as id limit 1;',$1) using $1;
RETURN;
END
$$;
Teste:
select test('tabel_view');
SaÃda atual:
Erro SQL [42P02]: ERRO: não há parâmetro $1
Onde: teste de função PL/pgSQL (caractere variável) linha 3 em EXECUTE
O mesmo funciona para CREATE TABLE
:
CREATE OR REPLACE FUNCTION test(name varchar) RETURNS void LANGUAGE plpgsql AS $$
BEGIN
EXECUTE format('create table %I as select $1 as id limit 1;',$1) using $1;
RETURN;
END
$$;
Estou tentando dessa maneira porque a concatenação de strings é propensa à injeção de SQL. Além disso, a UDF em que estou trabalhando terá um array como entrada.
Alguma ideia de como resolver esse problema?
A
USING
cláusula deEXECUTE
serve para passar valores para comandos DML ("comandos utilitários"). O manual:Não funciona com comandos DDL como
CREATE VIEW
. ASELECT
instrução inCRATE TABLE
é diferente porque é tratada (e executada) como umaSELECT
instrução aninhada real, onde a interpolação de parâmetros é implementada. Ele se enquadra em "certos comandos contendo um destes" .Concatene o valor como string literal:
violino
O padrão da string literal é type
text
. Adicione uma conversão de tipo explÃcita se precisar de um tipo diferente - como para um tipo de array que você mencionou.