如果 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?