Postgresql 如何在postgres中创建表并插入具有动态值的数据
我正在尝试编写一个存储过程,其中表名是动态出现的。 它还必须检查表是否已经存在,并仅在不存在时创建 然后,稍后我尝试将数据插入表中,如下所示。 这里我将Postgresql 如何在postgres中创建表并插入具有动态值的数据,postgresql,stored-procedures,plpgsql,Postgresql,Stored Procedures,Plpgsql,我正在尝试编写一个存储过程,其中表名是动态出现的。 它还必须检查表是否已经存在,并仅在不存在时创建 然后,稍后我尝试将数据插入表中,如下所示。 这里我将pkey和filedata作为参数传递给插入查询,其中pkey是一个字符串,filedata是一个json数据,看起来像{“客户”:“约翰·多伊”,“物品”:{“产品”:“啤酒”,“数量”:6} 我已经尝试了下面的查询,但是表没有被创建,而是给出了消息 注意:标识符public.tablename_11111将被截断为public.tablena
pkey
和filedata
作为参数传递给插入查询,其中pkey
是一个字符串,filedata
是一个json数据,看起来像{“客户”:“约翰·多伊”,“物品”:{“产品”:“啤酒”,“数量”:6}
我已经尝试了下面的查询,但是表没有被创建,而是给出了消息
注意:标识符public.tablename_11111将被截断为public.tablename_11111
这里的表名是public.tablename\u11111
CREATE OR REPLACE FUNCTION public.generate_table(tb_name text)
RETURNS text LANGUAGE 'plpgsql'
COST 100 VOLATILE AS $BODY$
BEGIN
EXECUTE format('
CREATE TABLE IF NOT EXISTS %I(
id serial PRIMARY KEY,
pkey VARCHAR (250) NULL,
fpo_data TEXT NULL
)', tb_name || '_pk');
EXECUTE 'INSERT INTO' || tb_name || '_pk (pkey, fpo_data) VALUES
('|| pkey ||', '|| filedata ||')';
END;
$BODY$;
第一:
%I
,当与类似于public.tablename_11111
的名称一起使用时,将不会执行您想要的操作
您将得到一个名为“public.tablename\u11111”的表,而不是架构public
中的表tablename\u11111
。为此,应将架构和表名分开,并使用格式%I.%I
:
EXECUTE
format(
'CREATE TABLE %I.%I (...)',
schema_name, tb_name || '_pk'
);
其次,您的
INSERT
语句容易受到SQL注入的攻击。您还必须使用format
函数,就像在CREATE TABLE
中一样,理想情况下,您应该将schema name和TABLE name作为两个单独的值传递。最好不要将值连接到SQL字符串中,而是使用占位符。主要是为了不必担心格式是否正确
如下所示:
CREATE OR REPLACE FUNCTION public.generate_table(tb_schema text, tb_name text, ???)
RETURNS text
LANGUAGE plpgsql --<< the language name is an identifier, don't quote it
COST 100 VOLATILE
AS $BODY$
BEGIN
tb_name := tb_name ||'_pk';
EXECUTE format('
CREATE TABLE IF NOT EXISTS %I.%I (
id serial PRIMARY KEY,
pkey VARCHAR (250) NULL,
fpo_data TEXT NULL
)', tb_schema, tb_name);
-- where do pkey and filedata come from?
EXECUTE format('INSERT INTO %I.%I (pkey, fpo_data) VALUES (:1, :2)',
tb_schema, tb_name)
using pkey, filedata;
END;
$BODY$;
创建或替换函数public.generate_表(tb_架构文本,tb_名称文本,?)
返回文本
语言plpgsql--我尝试将%I替换为%I。%n我得到以下错误:format()的参数太少。对,我说过应该将架构和表名分开。我应该说:让schema和table成为两个不同的函数参数,并将它们都输入到格式中。格式字符串中的每个%
模式必须有相应的参数。请键入它。我不明白你到底想说什么。我尝试了您的代码存储过程现在运行正常,但是当我尝试运行select*from public.tablename_11111时,我得到的错误类似于关系“public.tablename_11111”不存在否,不能。您真正运行的必须是“public.tablename_11111”中的select*代码>。请注意,双引号使PostgreSQL将其视为单个标识符,而不是模式限定表。也许你正在使用某种工具,误导性地为你添加这些引用。