postgresql – 如何从执行的预准备语句中获取$1参数的值(使用current_query()在触发器内)

postgresql – 如何从执行的预准备语句中获取参数的值(使用current_query()在触发器内),第1张

概述在触发器中我想看看sql查询触发了这个触发器.我使用了 postgresql(8.4)的current_query()函数. 一切都很好,但是如果触发器是通过预备语句执行的,我会获得占位符($1)而不是正确的值.例如(已记录的查询): delete from some_table where id=$1 有没有办法获得/拥有这个值/参数? 已编辑(已添加示例): --table for savin 在触发器中我想看看SQL查询触发了这个触发器.我使用了 postgresql(8.4)的current_query()函数.

一切都很好,但是如果触发器是通过预备语句执行的,我会获得占位符($1)而不是正确的值.例如(已记录的查询):

delete from some_table where ID=

有没有办法获得/拥有这个值/参数?

已编辑(已添加示例):

--table for saving querycreate table log_table (query text)--table for triggercreate table some_table (ID text)--function itselfCREATE FUNCTION save_query() RETURNS trigger AS $$    switch $TG_op {    DELETE {            spi_exec "INSERT INTO log_table (query) VALUES (current_query())"        }    default {            return OK        }    }    return OK$$LANGUAGE pltcl;

创建一个触发器:

create trigger test_trigger before delete on some_table for each row execute procedure save_query();

准备好的语句是从hibernate执行的.

再次编辑(添加了java部分)

import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;public class DeleteUsingPreparedStmt {    public static voID main(String[] args) {        try {            String deleteString = "delete from floors where ID = ? ";            final int IDToDelte = 1;            Class.forname("org.postgresql.Driver");            String url = "jdbc:postgresql://127.0.0.1:5432/YOUR_DATABASE";            Connection conn = DriverManager.getConnection(url,"user","password");            PreparedStatement deleteStmt = conn.prepareStatement(deleteString);            deleteStmt.setInt(1,IDToDelte);            deleteStmt.executeUpdate();        } catch (Exception e) {            //hIDe me :)        }    }}

你需要一个jdbc驱动程序 – click.

这是一些工作代码(对于Debian用户:只需安装postgresql-pltcl-8.4包并运行CREATE LANGUAGE pltcl;)
CREATE table log_table (    ID serial,query text);CREATE table floors (    ID serial,value text);INSERT INTO floors(value) VALUES ('aaa'),('bbb');CREATE OR REPLACE FUNCTION save_query() RETURNS trigger AS $$    switch $TG_op {        DELETE {            spi_exec "INSERT INTO log_table (query) VALUES (current_query())"        }        default {            return OK        }    }    return OK$$LANGUAGE pltcl;CREATE TRIGGER test_trigger    BEFORE DELETE ON floors    FOR EACH ROW    EXECUTE PROCEDURE save_query();

但是我无法在预准备语句中获取占位符(它返回EXECUTE deleteFromFloors(2);):

table log_table; ID | query ----+-------(0 rows)DELETE FROM floors WHERE ID = 1;DELETE 1table log_table; ID |              query               ----+----------------------------------  1 | DELETE FROM floors WHERE ID = 1;(1 row)PREPARE deleteFromFloors(integer) AS    DELETE FROM floors WHERE ID = ;PREPAREEXECUTE deleteFromFloors(2);DELETE 1table log_table; ID |              query               ----+----------------------------------  1 | DELETE FROM floors WHERE ID = 1;  2 | EXECUTE deleteFromFloors(2);(2 rows)

编辑:

作为一种解决方法使用olD记录(在Tcl中表示为数组),从那里获取ID列并使用replace函数来代替$1.这里有两个解决方案:PL / pgsql和PL / Tcl:

CREATE OR REPLACE FUNCTION save_query() RETURNS TRIGGER AS $$BEGIN    INSERT INTO log_table (query)        VALUES (replace(current_query(),'',olD.ID::text));    RETURN olD;END;$$LANGUAGE plpgsql;CREATE OR REPLACE FUNCTION save_query() RETURNS trigger AS $$    switch $TG_op {        DELETE {            spi_exec "INSERT INTO log_table (query)                VALUES (replace(current_query(),'$1','$olD(ID)'))"        }        default {            return OK        }    }    return OK$$LANGUAGE pltcl;

结果:

java -classpath '.:postgresql-8.4-702.jdbc4.jar' DeleteUsingPreparedStmttable log_table; ID |              query              ----+---------------------------------  1 | delete from floors where ID = 1

(1排)

总结

以上是内存溢出为你收集整理的postgresql – 如何从执行的预准备语句中获取$1参数的值(使用current_query()在触发器内)全部内容,希望文章能够帮你解决postgresql – 如何从执行的预准备语句中获取$1参数的值(使用current_query()在触发器内)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/1181934.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存