在Postgres(plpgsql)中用单引号替换双引号
我正在为分区表在plpgsql中构建一个触发函数,并且所有逻辑都可以正常工作,但是在将实际记录插入到表中时遇到了麻烦.
I am building a trigger function in plpgsql for my partitioned table and I've got all of my logic working, but am having trouble inserting the actual record into my table.
我必须通过变量引用来引用我的特定表,以便(据我所知)迫使我使用EXECUTE
命令,如下所示:
I have to reference my specific table by a variable reference, so that (as far as I understand) forces me to use an EXECUTE
command, as so:
EXECUTE 'INSERT INTO ' || tablename || ' VALUES ' || NEW.*;
但是,这不能以Postgres的INSERT
函数可以理解的方式来解压缩存储在NEW
中的记录.它将记录转换为字符串,同时保留其中所有的双引号. IE.上面的代码在执行后变成了以下内容:
However, this does not handle unpacking the record stored in NEW
in a way that Postgres' INSERT
function can understand. It converts the record into a string while preserving all of the double quotes within. I.e. the above turns into the following upon execution:
INSERT INTO cfs_hgt_05152016_05202016
VALUES ("2016-05-16 00:00:00","2016-05-12 06:00:00",HGT,"1000 mb",9,-71,-38.5371)
问题在于Postgres认为由于双引号,这些值现在是列.
The problem with this is Postgres thinks these values are now columns due to the double quotes.
COPY cfs_hgt_master, line 1: ""2016-05-16 00:00:00","2016-05-12 06:00:00","HGT","1000 mb",9,-71,-38.5371"
ERROR: column "2016-05-16 00:00:00" does not exist
我尝试通过以下方法对此进行补救:
I tried to remedy this by the following:
record_text := regexp_replace(NEW.*, '"', '\'', 'gi');
EXECUTE 'INSERT INTO ' || tablename || ' VALUES ' || record_text;
但是像这样转义单引号会产生错误:
But escaping the single quote like that produces an error:
psql:cfs_hgt_trigger_function.sql:36: ERROR: unterminated quoted string at or near "' || record_text;
LINE 30: ... EXECUTE 'INSERT INTO ' || tablename || ' VALUES ' || recor...
^
有人可以帮助我弄清楚如何适当地避免使用单引号,或者建议完成我的任务的另一种方法吗?
Could someone help me figure out how to either properly escape that single quote, or suggest an alternative means of accomplishing my task?
完全不要将值转换为其文本表示形式 .使用 USING
子句传递值的EXECUTE
.
Don't convert values to their text representation at all. Pass values with the USING
clause of EXECUTE
.
并正确转义表名.您可以使用 format()
为此:
And escape table names properly. You can use format()
for this:
EXECUTE format('INSERT INTO %I SELECT $1.*', tablename)
USING NEW;
详细信息:
- INSERT with dynamic table name in trigger function
- How to pass NEW.* to EXECUTE in trigger function