sql >> Database teknologi >  >> RDS >> PostgreSQL

Postgres finder alle rækker i databasetabeller, der matcher kriterier i en given kolonne

Jeg tog mig tid til at få det til at fungere for dig.

Til at begynde med, nogle oplysninger om, hvad der foregår inde i koden.

Forklaring

  1. funktionen tager to input-argumenter:kolonnenavn og kolonneværdi
  2. det kræver en oprettet type, som det vil returnere et sæt af
  3. første sløjfe identificerer tabeller, der har et kolonnenavn angivet som input-argument
  4. derefter danner den en forespørgsel, som samler alle rækker, der matcher inputbetingelsen i hver tabel taget fra trin 3 med sammenligning baseret på ILIKE - som i dit eksempel
  5. funktionen går kun ind i den anden sløjfe, hvis der er mindst én række i den aktuelt besøgte tabel, der matcher den angivne betingelse (så er arrayet ikke null)
  6. Anden sløjfe fjerner arrayet af rækker, der matcher betingelsen, og for hvert element sætter den det i funktionsoutputtet med RETURN NEXT rec klausul

Bemærkninger

  • At søge med LIKE er ineffektivt - jeg foreslår, at du tilføjer et andet input-argument "kolonnetype" og begrænser det i opslag ved at tilføje en join til pg_catalog.pg_type tabel.

  • Den anden løkke er der, så hvis der findes mere end 1 række for en bestemt tabel, så returneres hver række.

  • Hvis du leder efter noget andet, som du har brug for nøgle-værdi-par, ikke kun værdierne, så skal du udvide funktionen. Du kan for eksempel bygge json-format fra rækker.

Nu til koden.

Testcase

CREATE TABLE tbl1 (col1 int, id int); -- does contain values
CREATE TABLE tbl2 (col1 int, col2 int); -- doesn't contain column "id"
CREATE TABLE tbl3 (id int, col5 int); -- doesn't contain values

INSERT INTO tbl1 (col1, id)
  VALUES (1, 5), (1, 33), (1, 25);

Tabel gemmer data:

postgres=# select * From tbl1;

 col1 | id
------+----
    1 |  5
    1 | 33
    1 | 25
(3 rows)

Oprettelse af type

CREATE TYPE sometype AS ( schemaname text, tablename text, colname text, entirerow text );

Funktionskode

CREATE OR REPLACE FUNCTION search_tables_for_column (
    v_column_name text
  , v_column_value text
)
RETURNS SETOF sometype
LANGUAGE plpgsql
STABLE
AS
$$
DECLARE
  rec           sometype%rowtype;
  v_row_array   text[];
  rec2          record;
  arr_el        text;
BEGIN
FOR rec IN
  SELECT 
      nam.nspname AS schemaname
    , cls.relname AS tablename
    , att.attname AS colname
    , null::text AS entirerow
  FROM 
    pg_attribute att
    JOIN pg_class cls ON att.attrelid = cls.oid 
    JOIN pg_namespace nam ON cls.relnamespace = nam.oid 
  WHERE 
    cls.relkind = 'r'
    AND att.attname = v_column_name
LOOP
  EXECUTE format('SELECT ARRAY_AGG(row(tablename.*)::text) FROM %I.%I AS tablename WHERE %I::text ILIKE %s',
    rec.schemaname, rec.tablename, rec.colname, quote_literal(concat('%',v_column_value,'%'))) INTO v_row_array;
  IF v_row_array is not null THEN
    FOR rec2 IN
      SELECT unnest(v_row_array) AS one_row
    LOOP
      rec.entirerow := rec2.one_row;
      RETURN NEXT rec;
    END LOOP;
  END IF;
END LOOP;
END
$$;

Eksemplarisk opkald og output

postgres=# select * from search_tables_for_column('id','5');

 schemaname | tablename | colname | entirerow
------------+-----------+---------+-----------
 public     | tbl1      | id      | (1,5)
 public     | tbl1      | id      | (1,25)
(2 rows)



  1. Geospatial punktkortlægning i flydende NHibernate

  2. SQL SERVER - Forstå hvordan MIN(tekst) virker

  3. Kopier tabel uden at kopiere data

  4. RDBMS vs NoSQL