AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 266540
Accepted
s.k
s.k
Asked: 2020-05-06 07:04:30 +0800 CST2020-05-06 07:04:30 +0800 CST 2020-05-06 07:04:30 +0800 CST

Defina var="NEW.this_word_column" em uma função de gatilho se "word" estiver presente em um nome de coluna

  • 772

Contexto

Estou usando o PostgreSQL 10.12.

Eu quero ser capaz de disparar uma função de gatilho em algumas tabelas específicas com dados geográficos.

Esta função de gatilho é projetada para criar um ponto PotGIS em uma coluna geomde late lonvalores.
Eu quero aplicar essa mesma função de gatilho em várias tabelas cada vez que uma nova linha é inserida.
A nomenclatura das colunas que contêm valores de latitude e longitude não é consistente nas tabelas, mas segue um padrão...

O que tenho 100% de certeza é que:
1. sempre há duas colunas contendo valores de latitude e longitude,
2. o nome dessas colunas nem sempre é o mesmo nas diferentes tabelas (caso contrário, seria muito simples), mas o palavra 'latitude' e a palavra 'longitude' sempre aparecem em seu nome e nunca aparecem em outros nomes de coluna.

Por exemplo, na tabela A:

_loc_longitude_e_loc_latitude_

e na tabela B:

_building_longitude_centere_building_latitude_center

por exemplo (+ muitos outros).

A função de disparo é a seguinte:

CREATE OR REPLACE FUNCTION make_point_with_latlon()
  RETURNS trigger AS
  $$
  DECLARE
      varlon := NULL;
      varlat := NULL;
  BEGIN
      IF to_jsonb(NEW) SIMILAR TO '.*longitude.*' THEN
          varlon := NEW.the_column_whith_longitude_in_its_name;
      END IF;
      IF to_jsonb(NEW) SIMILAR TO '.*latitude.*' THEN
          varlat := NEW.the_column_whith_latitude_in_its_name;
      END IF;
      NEW.geom = ST_MakePoint(varlon, varlat);
  END
  $$
LANGUAGE 'plpgsql';

Com os seguintes acionadores:

CREATE TRIGGER make_point_with_latlon_but
    BEFORE INSERT OR UPDATE ON schema.table1
    FOR EACH ROW
    EXECUTE PROCEDURE schema.make_point_with_latlon();

CREATE TRIGGER make_point_with_latlon_but
    BEFORE INSERT OR UPDATE ON schema.table2
    FOR EACH ROW
    EXECUTE PROCEDURE schema.make_point_with_latlon();

CREATE TRIGGER make_point_with_latlon_but
    BEFORE INSERT OR UPDATE ON schema.table3
    FOR EACH ROW
    EXECUTE PROCEDURE schema.make_point_with_latlon();

-- (...and many more other tables that need the same trigger).

Não sei como procurar o padrão .*latitude.*nos nomes das colunas passados ​​para a função e como obter seu valor em duas variáveis ​​que posso usar para construir o ponto.
E minhas habilidades de pesquisa no Google para pesquisar esse tipo de coisa estão longe de ser perfeitas, portanto, retornando resultados barulhentos.

Pergunta

Existe alguma possibilidade de fazer isso?

postgresql trigger
  • 1 1 respostas
  • 573 Views

1 respostas

  • Voted
  1. Best Answer
    McNets
    2020-05-06T07:40:31+08:002020-05-06T07:40:31+08:00

    Você pode usar visualizações INFORMATION_SCHEMA e variáveis ​​especiais: TG_TABLE_SCHEMA, TG_TABLE_NAME

    Citado de documentos:

    Quando uma função PL/pgSQL é chamada como trigger, várias variáveis ​​especiais são criadas automaticamente no bloco de nível superior. Eles são:

    TG_TABLE_NAME: Nome do tipo de dados; o nome da tabela que causou a invocação do gatilho.

    TG_TABLE_SCHEMA: Nome do tipo de dados; o nome do esquema da tabela que causou a chamada do gatilho.

    Dado o próximo exemplo:

    create table a (id int primary key, latitude int, longitude int);
    create table b (id int primary key, _loc_latitude int, _loc_longitude int);
    create table c (result text);
    
    create function trg_tables()
    returns trigger as
    $$
    declare
      varlat text;
      varlng text;
      cmd text;
      vallat int;
      vallng int;
    begin  
      varlat := (select column_name
                from   information_schema.columns
                where  table_schema = TG_TABLE_SCHEMA
                       and table_name = TG_TABLE_NAME
                       and column_name like '%latitude%');
    
      varlng := (select column_name
                from   information_schema.columns
                where  table_schema = TG_TABLE_SCHEMA
                       and table_name = TG_TABLE_NAME
                       and column_name like '%longitude%');
    
      execute 'select $1.' || varlat
      using NEW
      into vallat;
    
      execute 'select $1.' || varlng
      using NEW
      into vallng;
    
      execute format('insert into c values (''lat: '' || ''%s'' || ''  lng '' || ''%s'' )',
                     vallat::text, vallng::text);
    
      return NEW;
    end;
    $$
    language plpgsql;
    
    create trigger trg after insert on a
      for each row execute procedure trg_tables();
    create trigger trg after insert on b
      for each row execute procedure trg_tables(); 
    
    insert into a values (1,11,1);
    insert into b values (1,20,2);
    select * from c;
    
    | result         |
    | :------------- |
    | lat: 11  lng 1 |
    | lat: 20  lng 2 |
    

    db<>fique aqui

    É apenas um exemplo de como usar INFORMATION_SCHEMA e variáveis ​​especiais dentro de uma trigger, mas talvez um pro-user do Postgres possa lhe dar uma solução melhor.

    • 2

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve