PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como salvar um dado com vírgula em caractere variando que passa por um gatilho?


Você pode usar format() para tornar a criação de uma consulta SQL dinâmica muito mais fácil, pois ela lidará automaticamente com identificadores e literais corretamente. Uma coisa que as pessoas geralmente ignoram é que você pode expandir uma única expressão de registro para todas as suas colunas usando (...).* - isso também funciona para NEW e OLD gravar variáveis ​​em um gatilho, por exemplo select (new).*

Você também pode passar variáveis ​​para um SQL dinâmico com o using palavra-chave do execute declaração. Não há necessidade de converter o registro entre um registro e uma representação de texto.

Usando essa possibilidade, sua função de gatilho pode ser simplificada para:
DECLARE 
  l_sql text;
BEGIN
    IF TG_TABLE_SCHEMA = 'public' THEN
      newtable := TG_TABLE_NAME || '_actividad';
    ELSE
      newtable := TG_TABLE_SCHEMA || '_' || TG_TABLE_NAME || '_actividad';
    END IF;

    PERFORM creartablaactividad(TG_TABLE_SCHEMA, TG_TABLE_NAME);
    l_sql := 'INSERT INTO actividad.%I  SELECT current_user, current_timestamp, %L, ($1).*';

    IF TG_OP = 'DELETE' THEN
      execute format(l_sql, newtable, 'D') using OLD;
      RETURN OLD;
    ELSE
      -- covers UPDATE and INSERT
      execute format(l_sql, newtable, 'U') using NEW;
      RETURN NEW;
    END IF;

    RETURN NULL; -- result is ignored since this is an AFTER trigger
END;

Usando espaços reservados como %I e %L também torna possível definir o SQL real apenas uma vez e reutilizá-lo. Esses "parâmetros" são substituídos pelo format() função (que preserva o $1 )

Observe o uso de ($1).* dentro da string SQL. Isso fará com que o execute expanda o parâmetro de registro $1 a todas as suas colunas. O próprio registro é passado "nativamente" com o USING palavra-chave.

O uso de INSERT sem uma lista de colunas de destino (insert into some_table ... em vez de insert into some_table (col1, col2, ...) ... ) é uma coisa muito frágil de se fazer. Se a origem e o destino não corresponderem, a inserção pode falhar facilmente. .

Se você não executar relatórios massivos nas tabelas de auditoria (onde ter nomes de colunas explícitos seria muito mais eficiente), convém pensar em um gatilho de auditoria mais genérico usando um JSON ou HSTORE coluna para armazenar todo o registro. Existem vários gatilhos de auditoria prontos disponíveis: