转义PL / pgSQL变量

时间:2012-02-21 12:28:38

标签: postgresql plpgsql

我在PostgreSQL 9上有一个触发器:

CREATE OR REPLACE FUNCTION clients_update_billingdata_trigger()
RETURNS trigger AS
$BODY$
DECLARE
  columnsUpdate  TEXT;
BEGIN
   columnsUpdate := '';

   IF (NEW.rsocial IS DISTINCT FROM OLD.rsocial) THEN
      columnsUpdate := columnsUpdate || 'RSocial before: ' || OLD.rsocial || '. RSocial after: ' || NEW.rsocial || E'\n';
   END IF;

   IF (NEW.legalidentifier IS DISTINCT FROM OLD.legalidentifier) THEN
      columnsUpdate := columnsUpdate || 'ILegal before: ' || OLD.legalidentifier || '. ILegal after: ' || NEW.legalidentifier || E'\n';
   END IF;

   [...]

   IF (columnsUpdate != '') THEN
      SELECT dblink_exec ('dbname=xxx user=xxx password=xxxxx',
                          'INSERT INTO BillingDataUpdate (client_id, columnsupdate)
                           VALUES (''' || NEW.idclient || ''', ''' || columnsUpdate || ''');');
   END IF;
   RETURN NEW;
 END;
 $BODY$
 LANGUAGE plpgsql;

NEW.rsocial的值可以是,例如: Tommy的服务。如果我关闭触发器,记录会正确保存(在other表中,在客户端中),因为我使用pg_escape_string函数在PHP中转义字符串。问题是,如何逃避NEW.rsocial来运行触发器?

提前致谢。

2 个答案:

答案 0 :(得分:4)

函数quote_literalquote_nullable可能很有用。但请注意,这些是PostgreSQL函数,因此请确保DBLINK的另一面了解结果。

您可能还会看一下这部分文档:

http://www.postgresql.org/docs/9.1/interactive/plpgsql-statements.html#PLPGSQL-QUOTE-LITERAL-EXAMPLE

修改

quote_xyz不得应用于rsocial的使用,而应适用于dblink_exec

  SELECT dblink_exec ('dbname=xxx user=xxx password=xxxxx',
                      'INSERT INTO BillingDataUpdate (client_id, columnsupdate) '
                       || 'VALUES (' || quote_nullable(NEW.idclient) || ', ' 
                       || quote_nullable(columnsUpdate) || ');');

请注意字符串连接中'的更改次数。

答案 1 :(得分:1)

尽管该帖子已经有了可接受的答案,但我建议使用the FORMAT function

FORMAT(E'%s', YOUR_VARIABLE)