使用 ALTER TABLE 动态添加新列的函数

Function to add new column dynamically with ALTER TABLE

我正在尝试向 table 动态添加一个字段。我创建了一个函数并传递了我想要创建的字段名称和数据类型:

CREATE OR REPLACE function "trustedforms2"."parametertest"("_pname" varchar)
 AS $BODY$BEGIN
    -- Routine body goes here...
ALTER TABLE byoung.formdata ADD COLUMN _pname varchar(255); 

END$BODY$
  LANGUAGE plpgsql

无论我传递的值如何,这总是会创建一个名为“_pname”的字段。如何获得按值而不是文字评估变量的函数?我尝试了 "_pname"'_pname'%1 %_pname,要么得到一个错误,要么得到一个名为“_pname”的字段。

好的,解决了

CREATE OR REPLACE PROCEDURE "trustedforms2"."parametertest"("_pname" varchar)
 AS $BODY$BEGIN
EXECUTE 'ALTER TABLE byoung.formdata ADD COLUMN ' || _pname || ' varchar(255)' ; 

END$BODY$
  LANGUAGE plpgsql

使用动态 SQL 时,请务必引用/转义已正确转换为代码的用户输入,以避免 SQL 注入 的攻击向量!基础知识:

此外,Postgres 标识符仅在 double-quoted:

时保留大写
  • Are PostgreSQL column names case-sensitive?

您例程的基本安全版本:

CREATE OR REPLACE PROCEDURE trustedforms2.parametertest(_pname text)
  LANGUAGE plpgsql AS
$proc$
BEGIN
   EXECUTE format('ALTER TABLE byoung.formdata ADD COLUMN %I varchar(255)', _pname); 
END
$proc$;

大写字母以这种方式保留。要强制使用 lower-case 个名称,请改用 lower(_pname)。 (您仍然希望 double-quote 标识符正确!)

您可能想也可能不想先检查 table 是否存在,以及该列是否不存在。如果这些假设不成立,简单形式会引发异常。

您可以使用 PROCEDURE for this like you chose in your answer, but remember to execute it with CALL:

CALL trustedforms2.parametertest('my_columns_name');

我可能会坚持使用(更常见的)功能。

而类型varchar(255)通常是 Postgres 中的误解: