如果 psql 函数和调用函数中存在则截断
Truncate if exists in psql function and call function
我有以下代码来创建一个函数,如果 table 不为空,则截断 table web_channel2
中的所有行:
create or replace function truncate_if_exists(tablename text)
returns void language plpgsql as $$
begin
select
from information_schema.tables
where table_name = tablename;
if found then
execute format('truncate %I', tablename);
end if;
end $$;
很遗憾,我不知道该如何继续......
如何执行函数?
TLDR
要执行 Postgres 函数(返回 void),请用 SELECT
:
调用它
SELECT truncate_if_exists('web_channel2');
正确的解决方案
... how should I continue?
再次删除函数。
DROP FUNCTION truncate_if_exists(text);
它不提供任何方法来 schema-qualify table。使用它可能会截断错误的 table ...
如果 table 不存在,您似乎正试图避免异常。
而您只想截断...
if the table is not empty
为此,我可能会使用这样的 safe 函数:
CREATE OR REPLACE FUNCTION public.truncate_if_exists(_table text, _schema text DEFAULT NULL)
RETURNS text
LANGUAGE plpgsql AS
$func$
DECLARE
_qual_tbl text := concat_ws('.', quote_ident(_schema), quote_ident(_table));
_row_found bool;
BEGIN
IF to_regclass(_qual_tbl) IS NOT NULL THEN -- table exists
EXECUTE 'SELECT EXISTS (SELECT FROM ' || _qual_tbl || ')'
INTO _row_found;
IF _row_found THEN -- table is not empty
EXECUTE 'TRUNCATE ' || _qual_tbl;
RETURN 'Table truncated: ' || _qual_tbl;
ELSE -- optional!
RETURN 'Table exists but is empty: ' || _qual_tbl;
END IF;
ELSE -- optional!
RETURN 'Table not found: ' || _qual_tbl;
END IF;
END
$func$;
要执行,用SELECT
调用:
SELECT truncate_if_exists('web_channel2');
如果未提供模式,函数将回退到遍历 search_path
- 就像您原来的那样。如果那是不可靠的,或者一般来说,为了安全起见(在截断 tables 时这似乎是谨慎的做法!)明确提供模式:
SELECT truncate_if_exists('web_channel2', 'my_schema');
db<>fiddle here
将标识符作为 字符串 提供时,您需要使用准确的大写字母。
为什么自定义变量 _row_found
而不是 FOUND
?参见:
- Dynamic SQL (EXECUTE) as condition for IF statement
基础知识:
Table name as a PostgreSQL function parameter
How to check if a table exists in a given schema
PL/pgSQL checking if a row exists
How does the search_path influence identifier resolution and the "current schema"
Are PostgreSQL column names case-sensitive?
我有以下代码来创建一个函数,如果 table 不为空,则截断 table web_channel2
中的所有行:
create or replace function truncate_if_exists(tablename text)
returns void language plpgsql as $$
begin
select
from information_schema.tables
where table_name = tablename;
if found then
execute format('truncate %I', tablename);
end if;
end $$;
很遗憾,我不知道该如何继续...... 如何执行函数?
TLDR
要执行 Postgres 函数(返回 void),请用 SELECT
:
SELECT truncate_if_exists('web_channel2');
正确的解决方案
... how should I continue?
再次删除函数。
DROP FUNCTION truncate_if_exists(text);
它不提供任何方法来 schema-qualify table。使用它可能会截断错误的 table ...
如果 table 不存在,您似乎正试图避免异常。
而您只想截断...
if the table is not empty
为此,我可能会使用这样的 safe 函数:
CREATE OR REPLACE FUNCTION public.truncate_if_exists(_table text, _schema text DEFAULT NULL)
RETURNS text
LANGUAGE plpgsql AS
$func$
DECLARE
_qual_tbl text := concat_ws('.', quote_ident(_schema), quote_ident(_table));
_row_found bool;
BEGIN
IF to_regclass(_qual_tbl) IS NOT NULL THEN -- table exists
EXECUTE 'SELECT EXISTS (SELECT FROM ' || _qual_tbl || ')'
INTO _row_found;
IF _row_found THEN -- table is not empty
EXECUTE 'TRUNCATE ' || _qual_tbl;
RETURN 'Table truncated: ' || _qual_tbl;
ELSE -- optional!
RETURN 'Table exists but is empty: ' || _qual_tbl;
END IF;
ELSE -- optional!
RETURN 'Table not found: ' || _qual_tbl;
END IF;
END
$func$;
要执行,用SELECT
调用:
SELECT truncate_if_exists('web_channel2');
如果未提供模式,函数将回退到遍历 search_path
- 就像您原来的那样。如果那是不可靠的,或者一般来说,为了安全起见(在截断 tables 时这似乎是谨慎的做法!)明确提供模式:
SELECT truncate_if_exists('web_channel2', 'my_schema');
db<>fiddle here
将标识符作为 字符串 提供时,您需要使用准确的大写字母。
为什么自定义变量 _row_found
而不是 FOUND
?参见:
- Dynamic SQL (EXECUTE) as condition for IF statement
基础知识:
Table name as a PostgreSQL function parameter
How to check if a table exists in a given schema
PL/pgSQL checking if a row exists
How does the search_path influence identifier resolution and the "current schema"
Are PostgreSQL column names case-sensitive?