Postgresql
如何在 plpgsql 過程中參數化 DDL?
如何在 plpgsql 過程中參數化 DDL 語句?也就是說,我想使用
org_label
參數作為角色和模式名稱,但下面的程式碼從字面上理解它,我最終得到了角色“org_label”:create or replace procedure create_org_schema (org_label varchar(63)) -- max identifier len in pgsql is 63 language plpgsql AS $$ BEGIN create role org_label IN GROUP organization; GRANT org_label TO ardoq_api_customers; -- so that AUTHORIZATION... below works CREATE SCHEMA AUTHORIZATION org_label; SET ROLE org_label; GRANT USAGE on SCHEMA org_label to ardoq_api_customers; -- so that we can list it RESET ROLE; END $$;
我試圖將第一行更改為:
EXECUTE 'create role $1 IN GROUP organization' USING org_label;
但這失敗了:
ERROR: syntax error at or near "$1" at character 13 QUERY: create role $1 IN GROUP organization
你不能。手冊:
參數符號的另一個限制是它們僅適用於
SELECT
、INSERT
、UPDATE
和DELETE
命令。在其他語句類型(通常稱為實用程序語句)中,您必須以文本方式插入值,即使它們只是數據值。
EXECUTE .. USING
不適用於此。您必須在執行之前連接查詢字元串。通常,format()
最方便的是安全地做到這一點:CREATE OR REPLACE PROCEDURE create_org_schema (org_label varchar(63)) -- max identifier len in pgsql is 63 LANGUAGE plpgsql AS $func$ BEGIN EXECUTE format ('CREATE ROLE %I IN GROUP organization', org_label); -- ... END $func$;
請注意使用格式說明符
%I
來正確引用標識符並防止可能的 SQL 注入。使用合法的小寫名稱讓您的 Postgres 生活簡單。看: