Làm thế nào để tìm kiếm một giá trị cụ thể trong tất cả các bảng (PostgreSQL)?


111

Có thể tìm kiếm mọi cột của mọi bảng cho một giá trị cụ thể trong PostgreSQL không?

Một câu hỏi tương tự có sẵn ở đây cho Oracle.


Bạn đang tìm kiếm một công cụ hoặc để thực hiện các quy trình được hiển thị trong câu hỏi được liên kết?
a_horse_with_no_name

Không, chỉ là cách đơn giản nhất để tìm một giá trị cụ thể trong tất cả các trường / bảng.
Sandro Munda

Vì vậy, bạn không muốn sử dụng một công cụ bên ngoài?
a_horse_with_no_name

1
Nếu đó là cách đơn giản nhất => ok cho một công cụ bên ngoài :-)
Sandro Munda

Câu trả lời:


131

Làm thế nào về việc kết xuất nội dung của cơ sở dữ liệu, sau đó sử dụng grep?

$ pg_dump --data-only --inserts -U postgres your-db-name > a.tmp
$ grep United a.tmp
INSERT INTO countries VALUES ('US', 'United States');
INSERT INTO countries VALUES ('GB', 'United Kingdom');

Tiện ích tương tự, pg_dump, có thể bao gồm tên cột trong đầu ra. Chỉ cần thay đổi --insertsthành --column-inserts. Bằng cách đó, bạn cũng có thể tìm kiếm các tên cột cụ thể. Nhưng nếu tôi đang tìm kiếm tên cột, có lẽ tôi sẽ kết xuất lược đồ thay vì dữ liệu.

$ pg_dump --data-only --column-inserts -U postgres your-db-name > a.tmp
$ grep country_code a.tmp
INSERT INTO countries (iso_country_code, iso_country_name) VALUES ('US', 'United  States');
INSERT INTO countries (iso_country_code, iso_country_name) VALUES ('GB', 'United Kingdom');

5
+1 miễn phí và đơn giản. Và nếu bạn muốn cấu trúc pg_dump cũng có thể làm điều đó. Ngoài ra, nếu grep không phải là thứ của bạn, hãy sử dụng công cụ tìm kiếm nội dung tệp mà bạn muốn trên các cấu trúc và / hoặc dữ liệu bị loại bỏ.
Kuberchaun

Nếu bạn muốn grep dữ liệu văn bản (thường được mã hóa trong các phiên bản postgres mới hơn), bạn có thể cần ALTER DATABASE your_db_name SET bytea_output = 'escape';vào cơ sở dữ liệu (hoặc một bản sao của nó) trước khi kết xuất nó. (Tôi không nhìn thấy một cách để xác định điều này chỉ dành riêng cho một pg_dumplệnh.)
Phils

bạn có thể giải thích chi tiết ..? Làm thế nào để tìm kiếm chuỗi 'ABC' trong tất cả các bảng?
Ông Bhosale

1
Nếu đang sử dụng IntelliJ, bạn có thể chỉ cần nhấp chuột phải vào db của mình và chọn "Kết xuất với 'pg_dump'" hoặc "Kết xuất dữ liệu vào (các) tệp"
Laurens

3
Làm thế nào đây là một giải pháp hợp lệ cho bất kỳ cơ sở dữ liệu nào đủ lớn mà bạn không thể kết xuất nó vào đĩa của mình?
Govind Parmar

76

Đây là một hàm pl / pgsql định vị các bản ghi trong đó bất kỳ cột nào chứa một giá trị cụ thể. Nó nhận các đối số là giá trị để tìm kiếm ở định dạng văn bản, một mảng tên bảng để tìm kiếm (mặc định cho tất cả các bảng) và một mảng tên lược đồ (mặc định cho tất cả các tên lược đồ).

Nó trả về cấu trúc bảng với giản đồ, tên bảng, tên cột và cột giả ctid(vị trí vật lý không bền của hàng trong bảng, xem Cột Hệ thống )

CREATE OR REPLACE FUNCTION search_columns(
    needle text,
    haystack_tables name[] default '{}',
    haystack_schema name[] default '{}'
)
RETURNS table(schemaname text, tablename text, columnname text, rowctid text)
AS $$
begin
  FOR schemaname,tablename,columnname IN
      SELECT c.table_schema,c.table_name,c.column_name
      FROM information_schema.columns c
        JOIN information_schema.tables t ON
          (t.table_name=c.table_name AND t.table_schema=c.table_schema)
        JOIN information_schema.table_privileges p ON
          (t.table_name=p.table_name AND t.table_schema=p.table_schema
              AND p.privilege_type='SELECT')
        JOIN information_schema.schemata s ON
          (s.schema_name=t.table_schema)
      WHERE (c.table_name=ANY(haystack_tables) OR haystack_tables='{}')
        AND (c.table_schema=ANY(haystack_schema) OR haystack_schema='{}')
        AND t.table_type='BASE TABLE'
  LOOP
    FOR rowctid IN
      EXECUTE format('SELECT ctid FROM %I.%I WHERE cast(%I as text)=%L',
       schemaname,
       tablename,
       columnname,
       needle
      )
    LOOP
      -- uncomment next line to get some progress report
      -- RAISE NOTICE 'hit in %.%', schemaname, tablename;
      RETURN NEXT;
    END LOOP;
 END LOOP;
END;
$$ language plpgsql;

Xem thêm phiên bản trên github dựa trên nguyên tắc tương tự nhưng bổ sung một số cải tiến về tốc độ và báo cáo.

Ví dụ về việc sử dụng trong cơ sở dữ liệu thử nghiệm:

  • Tìm kiếm trong tất cả các bảng trong lược đồ công khai:
select * from search_columns ('foobar');
 tên lược đồ | tên bảng | tên cột | rowctid
------------ + ----------- + ------------ + ---------
 công khai | s3 | tên sử dụng | (0,11)
 công khai | s2 | tên đăng nhập | (7,29)
 công khai | w | cơ thể | (0,2)
(3 hàng)
  • Tìm kiếm trong một bảng cụ thể:
 select * from search_columns ('foobar', '{w}');
 tên lược đồ | tên bảng | tên cột | rowctid
------------ + ----------- + ------------ + ---------
 công khai | w | cơ thể | (0,2)
(1 hàng)
  • Tìm kiếm trong một tập hợp con các bảng có được từ một lựa chọn:
select * from search_columns ('foobar', array (chọn table_name :: name từ information_schema.tables nơi tên_bảng như 's%'), array ['public']);
 tên lược đồ | tên bảng | tên cột | rowctid
------------ + ----------- + ------------ + ---------
 công khai | s2 | tên đăng nhập | (7,29)
 công khai | s3 | tên sử dụng | (0,11)
(2 hàng)
  • Nhận một hàng kết quả với bảng cơ sở tương ứng và và ctid:
select * from public.w where ctid = '(0,2)';
 tiêu đề | cơ thể | tsv         
------- + -------- + ---------------------
 toto | foobar | 'foobar': 2 'toto': 1

Các biến thể

  • Để kiểm tra biểu thức chính quy thay vì bình đẳng nghiêm ngặt, như grep, phần này của truy vấn:

    SELECT ctid FROM %I.%I WHERE cast(%I as text)=%L

    có thể được thay đổi thành:

    SELECT ctid FROM %I.%I WHERE cast(%I as text) ~ %L

  • Đối với so sánh không phân biệt chữ hoa chữ thường, bạn có thể viết:

    SELECT ctid FROM %I.%I WHERE lower(cast(%I as text)) = lower(%L)


LỖI: lỗi cú pháp tại hoặc gần "mặc định" LINE 3: haystack_tables name [] default '{}' (Sử dụng PostgreSQL 8.2.17 và không thể nâng cấp)
Henno

@Henno: vâng nó yêu cầu PG-9.1. Đã chỉnh sửa ngay bây giờ để làm cho điều đó rõ ràng. Để sử dụng nó với các phiên bản cũ hơn, bạn sẽ phải điều chỉnh nó.
Daniel Vérité

1
@Rajendra_Prasad: toán tử biểu thức chính quy có biến thể không phân biệt chữ hoa chữ thường: ~*đầy đủ hơn so với low (). Nhưng dù sao thì đó t.*không phải là một phần của câu trả lời trên. Tìm kiếm theo cột không giống như tìm kiếm hàng dưới dạng giá trị vì các dấu phân cách cột.
Daniel Vérité

2
Điều này chỉ trả về một hàng cho mỗi lược đồ-bảng-cột.
theGtknerd

1
Cảm ơn rất nhiều. Giải pháp này hoạt động hoàn hảo cho tôi. Tôi phải tìm một bảng trong danh sách hơn 1000 bảng chứa một url cụ thể. Bạn đã cứu ngày của tôi !.
Sunil

7

để tìm kiếm mọi cột của mọi bảng cho một giá trị cụ thể

Điều này không xác định cách đối sánh chính xác.
Nó cũng không xác định chính xác những gì sẽ trả về.

Giả định:

  • Tìm bất kỳ hàng nào có bất kỳ cột nào chứa giá trị đã cho trong biểu diễn văn bản của nó - trái ngược với việc cân bằng giá trị đã cho.
  • Trả lại tên bảng ( regclass) và ID tuple ( ctid), vì đó là cách đơn giản nhất.

Đây là một cách đơn giản, nhanh chóng và hơi bẩn:

CREATE OR REPLACE FUNCTION search_whole_db(_like_pattern text)
  RETURNS TABLE(_tbl regclass, _ctid tid) AS
$func$
BEGIN
   FOR _tbl IN
      SELECT c.oid::regclass
      FROM   pg_class c
      JOIN   pg_namespace n ON n.oid = relnamespace
      WHERE  c.relkind = 'r'                           -- only tables
      AND    n.nspname !~ '^(pg_|information_schema)'  -- exclude system schemas
      ORDER BY n.nspname, c.relname
   LOOP
      RETURN QUERY EXECUTE format(
         'SELECT $1, ctid FROM %s t WHERE t::text ~~ %L'
       , _tbl, '%' || _like_pattern || '%')
      USING _tbl;
   END LOOP;
END
$func$  LANGUAGE plpgsql;

Gọi:

SELECT * FROM search_whole_db('mypattern');

Cung cấp mẫu tìm kiếm mà không cần kèm theo %.

Tại sao hơi bẩn?

Nếu dấu phân tách và dấu trang trí cho hàng trong textbiểu diễn có thể là một phần của mẫu tìm kiếm, thì có thể có kết quả dương tính giả:

  • dấu phân tách cột: ,theo mặc định
  • toàn bộ hàng được đặt trong dấu ngoặc đơn:()
  • một số giá trị được đặt trong dấu ngoặc kép "
  • \ có thể được thêm vào như thoát char

Và việc biểu diễn văn bản của một số cột có thể phụ thuộc vào cài đặt cục bộ - nhưng sự không rõ ràng đó là cố hữu đối với câu hỏi, không phải giải pháp của tôi.

Mỗi hàng đủ điều kiện chỉ được trả lại một lần , ngay cả khi nó khớp nhiều lần (trái ngược với các câu trả lời khác ở đây).

Điều này tìm kiếm toàn bộ DB ngoại trừ danh mục hệ thống. Thông thường sẽ mất nhiều thời gian để hoàn thành . Bạn có thể muốn giới hạn đối với một số lược đồ / bảng nhất định (hoặc thậm chí là các cột) như được trình bày trong các câu trả lời khác. Hoặc thêm thông báo và chỉ báo tiến độ, cũng được trình bày trong một câu trả lời khác.

Các regclassloại định danh đối tượng được biểu diễn dưới dạng tên bảng, lược đồ trình độ khi cần thiết để disambiguate theo hiện tại search_path:

ctidgì?

Bạn có thể muốn thoát các ký tự có ý nghĩa đặc biệt trong mẫu tìm kiếm. Xem:


Giải pháp tuyệt vời này thậm chí còn tốt hơn với low () - 'SELECT $ 1, ctid FROM% st WHERE
low

5

Và nếu ai đó nghĩ rằng nó có thể giúp ích. Đây là chức năng của @Daniel Vérité, với một tham số khác chấp nhận tên của các cột có thể được sử dụng trong tìm kiếm. Bằng cách này, nó làm giảm thời gian xử lý. Ít nhất trong thử nghiệm của tôi, nó đã giảm đi rất nhiều.

CREATE OR REPLACE FUNCTION search_columns(
    needle text,
    haystack_columns name[] default '{}',
    haystack_tables name[] default '{}',
    haystack_schema name[] default '{public}'
)
RETURNS table(schemaname text, tablename text, columnname text, rowctid text)
AS $$
begin
  FOR schemaname,tablename,columnname IN
      SELECT c.table_schema,c.table_name,c.column_name
      FROM information_schema.columns c
      JOIN information_schema.tables t ON
        (t.table_name=c.table_name AND t.table_schema=c.table_schema)
      WHERE (c.table_name=ANY(haystack_tables) OR haystack_tables='{}')
        AND c.table_schema=ANY(haystack_schema)
        AND (c.column_name=ANY(haystack_columns) OR haystack_columns='{}')
        AND t.table_type='BASE TABLE'
  LOOP
    EXECUTE format('SELECT ctid FROM %I.%I WHERE cast(%I as text)=%L',
       schemaname,
       tablename,
       columnname,
       needle
    ) INTO rowctid;
    IF rowctid is not null THEN
      RETURN NEXT;
    END IF;
 END LOOP;
END;
$$ language plpgsql;

Dưới đây là một ví dụ về cách sử dụng hàm tìm kiếm được tạo ở trên.

SELECT * FROM search_columns('86192700'
    , array(SELECT DISTINCT a.column_name::name FROM information_schema.columns AS a
            INNER JOIN information_schema.tables as b ON (b.table_catalog = a.table_catalog AND b.table_schema = a.table_schema AND b.table_name = a.table_name)
        WHERE 
            a.column_name iLIKE '%cep%' 
            AND b.table_type = 'BASE TABLE'
            AND b.table_schema = 'public'
    )

    , array(SELECT b.table_name::name FROM information_schema.columns AS a
            INNER JOIN information_schema.tables as b ON (b.table_catalog = a.table_catalog AND b.table_schema = a.table_schema AND b.table_name = a.table_name)
        WHERE 
            a.column_name iLIKE '%cep%' 
            AND b.table_type = 'BASE TABLE'
            AND b.table_schema = 'public')
);

5

Nếu không lưu trữ một thủ tục mới, bạn có thể sử dụng một khối mã và thực thi để có được một bảng các lần xuất hiện. Bạn có thể lọc kết quả theo tên lược đồ, bảng hoặc cột.

DO $$
DECLARE
  value int := 0;
  sql text := 'The constructed select statement';
  rec1 record;
  rec2 record;
BEGIN
  DROP TABLE IF EXISTS _x;
  CREATE TEMPORARY TABLE _x (
    schema_name text, 
    table_name text, 
    column_name text,
    found text
  );
  FOR rec1 IN 
        SELECT table_schema, table_name, column_name
        FROM information_schema.columns 
        WHERE table_name <> '_x'
                AND UPPER(column_name) LIKE UPPER('%%')                  
                AND table_schema <> 'pg_catalog'
                AND table_schema <> 'information_schema'
                AND data_type IN ('character varying', 'text', 'character', 'char', 'varchar')
        LOOP
    sql := concat('SELECT ', rec1."column_name", ' AS "found" FROM ',rec1."table_schema" , '.',rec1."table_name" , ' WHERE UPPER(',rec1."column_name" , ') LIKE UPPER(''','%my_substring_to_find_goes_here%' , ''')');
    RAISE NOTICE '%', sql;
    BEGIN
        FOR rec2 IN EXECUTE sql LOOP
            RAISE NOTICE '%', sql;
            INSERT INTO _x VALUES (rec1."table_schema", rec1."table_name", rec1."column_name", rec2."found");
        END LOOP;
    EXCEPTION WHEN OTHERS THEN
    END;
  END LOOP;
  END; $$;

SELECT * FROM _x;

Bạn chỉ định chuỗi tìm kiếm ở đâu? Hay đây chỉ là kết xuất toàn bộ DB, từng bảng?
jimtut

1
Tôi đã không tạo một tham số cho chuỗi. Bạn có thể mã hóa nó và chạy nó trực tiếp như một khối hoặc tạo một thủ tục được lưu trữ từ nó. Trong mọi trường hợp, chuỗi tìm kiếm của bạn ở đây nằm giữa hai dấu phần trăm: WHERE UPPER (', rec1. "Column_name",') LIKE UPPER ('' ',' %% ',' '')
profimedica

5

Có một cách để đạt được điều này mà không cần tạo một hàm hoặc sử dụng một công cụ bên ngoài. Bằng cách sử dụng query_to_xml()chức năng của Postgres có thể chạy động một truy vấn bên trong một truy vấn khác, bạn có thể tìm kiếm một văn bản trên nhiều bảng. Điều này dựa trên câu trả lời của tôi để truy xuất số lượng hàng cho tất cả các bảng :

Để tìm kiếm chuỗi footrên tất cả các bảng trong một lược đồ, có thể sử dụng cách sau:

with found_rows as (
  select format('%I.%I', table_schema, table_name) as table_name,
         query_to_xml(format('select to_jsonb(t) as table_row 
                              from %I.%I as t 
                              where t::text like ''%%foo%%'' ', table_schema, table_name), 
                      true, false, '') as table_rows
  from information_schema.tables 
  where table_schema = 'public'
)
select table_name, x.table_row
from found_rows f
  left join xmltable('//table/row' 
                     passing table_rows
                       columns
                         table_row text path 'table_row') as x on true

Lưu ý rằng việc sử dụng xmltableyêu cầu Postgres 10 hoặc mới hơn. Đối với phiên bản Postgres cũ hơn, điều này cũng có thể được thực hiện bằng cách sử dụng xpath ().

with found_rows as (
  select format('%I.%I', table_schema, table_name) as table_name,
         query_to_xml(format('select to_jsonb(t) as table_row 
                              from %I.%I as t 
                              where t::text like ''%%foo%%'' ', table_schema, table_name), 
                      true, false, '') as table_rows
  from information_schema.tables 
  where table_schema = 'public'
)
select table_name, x.table_row
from found_rows f
   cross join unnest(xpath('/table/row/table_row/text()', table_rows)) as r(data)

Biểu thức bảng chung ( WITH ...) chỉ được sử dụng để thuận tiện. Nó lặp qua tất cả các bảng trong publiclược đồ. Đối với mỗi bảng, truy vấn sau được chạy thông qua query_to_xml()hàm:

select to_jsonb(t)
from some_table t
where t::text like '%foo%';

Mệnh đề where được sử dụng để đảm bảo việc tạo nội dung XML đắt tiền chỉ được thực hiện cho các hàng có chứa chuỗi tìm kiếm. Điều này có thể trả về một cái gì đó như thế này:

<table xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
  <table_row>{"id": 42, "some_column": "foobar"}</table_row>
</row>
</table>

Việc chuyển đổi hàng hoàn chỉnh thành jsonbđược thực hiện để trong kết quả, người ta có thể thấy giá trị nào thuộc về cột nào.

Ở trên có thể trả lại một cái gì đó như thế này:

table_name   |   table_row
-------------+----------------------------------------
public.foo   |  {"id": 1, "some_column": "foobar"}
public.bar   |  {"id": 42, "another_column": "barfoo"}

Ví dụ trực tuyến cho Postgres 10+

Ví dụ trực tuyến cho các phiên bản Postgres cũ hơn


Tôi đang cố gắng chạy mã cho các phiên bản PostgreSQL cũ hơn và tôi gặp lỗi sauERROR: 42883: function format("unknown", information_schema.sql_identifier, information_schema.sql_identifier) does not exist
Matt

Bạn có thể cần truyền chúng:format('%I.%I', table_schema::text, table_name::text)
a_horse_with_no_name. 23/09/19

Được rồi, xong rồi, bây giờ tôi cóERROR: 42883: function format("unknown", character varying, character varying) does not exist
Matt

Sau đó, nhiều phiên bản Postgres của bạn là rất cũ, mà id thậm chí không có format()chức năng
a_horse_with_no_name

Tôi nghĩ rằng Redshift dựa trên 8.3?
Matt

3

Đây là chức năng của @Daniel Vérité với chức năng báo cáo tiến độ. Nó báo cáo tiến trình theo ba cách:

  1. bởi RAISE NOTICE;
  2. bằng cách giảm giá trị của chuỗi {process_seq} đã cung cấp từ {tổng số cột để tìm kiếm trong} xuống 0;
  3. bằng cách ghi tiến trình cùng với các bảng tìm được vào tệp văn bản, nằm trong c: \ windows \ temp \ {process_seq} .txt.

_

CREATE OR REPLACE FUNCTION search_columns(
    needle text,
    haystack_tables name[] default '{}',
    haystack_schema name[] default '{public}',
    progress_seq text default NULL
)
RETURNS table(schemaname text, tablename text, columnname text, rowctid text)
AS $$
DECLARE
currenttable text;
columnscount integer;
foundintables text[];
foundincolumns text[];
begin
currenttable='';
columnscount = (SELECT count(1)
      FROM information_schema.columns c
      JOIN information_schema.tables t ON
        (t.table_name=c.table_name AND t.table_schema=c.table_schema)
      WHERE (c.table_name=ANY(haystack_tables) OR haystack_tables='{}')
        AND c.table_schema=ANY(haystack_schema)
        AND t.table_type='BASE TABLE')::integer;
PERFORM setval(progress_seq::regclass, columnscount);

  FOR schemaname,tablename,columnname IN
      SELECT c.table_schema,c.table_name,c.column_name
      FROM information_schema.columns c
      JOIN information_schema.tables t ON
        (t.table_name=c.table_name AND t.table_schema=c.table_schema)
      WHERE (c.table_name=ANY(haystack_tables) OR haystack_tables='{}')
        AND c.table_schema=ANY(haystack_schema)
        AND t.table_type='BASE TABLE'
  LOOP
    EXECUTE format('SELECT ctid FROM %I.%I WHERE cast(%I as text)=%L',
       schemaname,
       tablename,
       columnname,
       needle
    ) INTO rowctid;
    IF rowctid is not null THEN
      RETURN NEXT;
      foundintables = foundintables || tablename;
      foundincolumns = foundincolumns || columnname;
      RAISE NOTICE 'FOUND! %, %, %, %', schemaname,tablename,columnname, rowctid;
    END IF;
         IF (progress_seq IS NOT NULL) THEN 
        PERFORM nextval(progress_seq::regclass);
    END IF;
    IF(currenttable<>tablename) THEN  
    currenttable=tablename;
     IF (progress_seq IS NOT NULL) THEN 
        RAISE NOTICE 'Columns left to look in: %; looking in table: %', currval(progress_seq::regclass), tablename;
        EXECUTE 'COPY (SELECT unnest(string_to_array(''Current table (column ' || columnscount-currval(progress_seq::regclass) || ' of ' || columnscount || '): ' || tablename || '\n\nFound in tables/columns:\n' || COALESCE(
        (SELECT string_agg(c1 || '/' || c2, '\n') FROM (SELECT unnest(foundintables) AS c1,unnest(foundincolumns) AS c2) AS t1)
        , '') || ''',''\n''))) TO ''c:\WINDOWS\temp\' || progress_seq || '.txt''';
    END IF;
    END IF;
 END LOOP;
END;
$$ language plpgsql;

3

- Hàm dưới đây sẽ liệt kê tất cả các bảng có chứa một chuỗi cụ thể trong cơ sở dữ liệu

 select TablesCount(‘StringToSearch’);

--Chuyển qua tất cả các bảng trong cơ sở dữ liệu

CREATE OR REPLACE FUNCTION **TablesCount**(_searchText TEXT)
RETURNS text AS 
$$ -- here start procedural part
   DECLARE _tname text;
   DECLARE cnt int;
   BEGIN
    FOR _tname IN SELECT table_name FROM information_schema.tables where table_schema='public' and table_type='BASE TABLE'  LOOP
         cnt= getMatchingCount(_tname,Columnames(_tname,_searchText));
                                RAISE NOTICE 'Count% ', CONCAT('  ',cnt,' Table name: ', _tname);
                END LOOP;
    RETURN _tname;
   END;
$$ -- here finish procedural part
LANGUAGE plpgsql; -- language specification

- Trả về số bảng mà điều kiện được đáp ứng. - Ví dụ: nếu văn bản dự định tồn tại trong bất kỳ trường nào của bảng, - thì số lượng sẽ lớn hơn 0. Chúng ta có thể tìm thấy thông báo - trong phần Tin nhắn của trình xem kết quả trong cơ sở dữ liệu postgres.

CREATE OR REPLACE FUNCTION **getMatchingCount**(_tname TEXT, _clause TEXT)
RETURNS int AS 
$$
Declare outpt text;
    BEGIN
    EXECUTE 'Select Count(*) from '||_tname||' where '|| _clause
       INTO outpt;
       RETURN outpt;
    END;
$$ LANGUAGE plpgsql;

--Nhận các trường của mỗi bảng. Tạo mệnh đề where với tất cả các cột của bảng.

CREATE OR REPLACE FUNCTION **Columnames**(_tname text,st text)
RETURNS text AS 
$$ -- here start procedural part
DECLARE
                _name text;
                _helper text;
   BEGIN
                FOR _name IN SELECT column_name FROM information_schema.Columns WHERE table_name =_tname LOOP
                                _name=CONCAT('CAST(',_name,' as VarChar)',' like ','''%',st,'%''', ' OR ');
                                _helper= CONCAT(_helper,_name,' ');
                END LOOP;
                RETURN CONCAT(_helper, ' 1=2');

   END;
$$ -- here finish procedural part
LANGUAGE plpgsql; -- language specification
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.