Jmo*_*y38 11 postgresql dynamic-sql plpgsql
使用 Postgres pl/pgsql,我尝试使用动态 EXECUTE 命令创建一个表,例如:
...
DECLARE
tblVar varchar := "myTable";
BEGIN
EXECUTE 'CREATE TABLE $1 (
foo integer NOT NULL,
bar varchar NOT NULL)'
USING _tblVar;
...
Run Code Online (Sandbox Code Playgroud)
但是,我继续收到错误消息
错误:“$1”处或附近的语法错误
如果我不使用$1
令牌,而是编写字符串,myTable
它就可以正常工作。
对 CREATE 调用使用动态语句是否有限制?
除了@filiprem 所写的内容之外,以下是您正确执行此操作的方法:
...
DECLARE
tbl_var text := 'myTable'; -- I would not use mixed case names ..
BEGIN
EXECUTE '
CREATE TABLE ' || quote_ident(tbl_var) || '(
foo integer NOT NULL,
bar text NOT NULL)';
...
Run Code Online (Sandbox Code Playgroud)
使用quote_ident()
以避免SQL注入或语法错误。它将引用带有非标准字符或保留字的名称。
我还用单引号替换了示例中字符串值周围的双引号。
请参阅http://www.postgresql.org/docs/9.1/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN
请注意,参数符号只能用于数据值——如果要使用动态确定的表名或列名,则必须以文本方式将它们插入到命令字符串中。例如,如果需要针对动态选择的表执行前面的查询,则可以执行以下操作:
Run Code Online (Sandbox Code Playgroud)EXECUTE 'SELECT count(*) FROM ' || tabname::regclass || ' WHERE inserted_by = $1 AND inserted <= $2' INTO c USING checked_user, checked_date;
正如下面的评论中所指出的,强制转换方法并不总是可行的,尤其是对于 CREATE 语句。考虑format
函数,例如:
EXECUTE format(
'CREATE TABLE %I (%I %I, %I %I)',
v_tabname,
v_col1name, v_col1type,
v_col2name, v_col2type);
Run Code Online (Sandbox Code Playgroud)
换句话说:
是的,有这样的限制。您不能为表/列名称使用参数 - 那是因为 Postgresql 需要能够在编译动态 SQL 语句时解析查询。解析器必须能够识别使用的关系。
旁注:可能此限制适用于其他 DBMS 中的动态 SQL,包括 Oracle:http : //download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/dynamic.htm#CHDHGHIF
归档时间: |
|
查看次数: |
49118 次 |
最近记录: |