注意:说我是postgresql的新手就是侮辱新手!
我正在编写一个Web应用程序,它将利用PostgreSQL数据库进行数据存储。在我到目前为止所做的工作中,我已经很好地掌握了创建查询和从中检索结果的语法,无论是查找,删除,插入还是更新。然而,我遇到了一个窘境。
为避免SQL注入问题,建议使用pg_prepare()/pg_execute()
或pg_query_params
。我使用的pg_prepare()/pg_execute()
比我更多。{1}}。但每个查询都是一个4步过程,
因为这是一个PHP脚本,所以在脚本终止时不会自动释放准备好的查询,因此需要通过以下调用手动完成:
pg_query($dbconn, "DEALLOCATE 'query_name';")
但是,DEALLOCATE
SQL命令不会返回有关成功或失败的有用信息,因此在尝试确定DEALLOCATE
指令的结果时,尝试确定是否为:
我的问题是双重的“
这个问题给出了部分解决方案,但找不到错误的来源没有帮助。 PHP/PostgreSQL: check if a prepared statement already exists
答案 0 :(得分:8)
取消分配语句时,pg_query
的返回值表示成功与否,就像任何“实用程序语句”一样。失败时它应该返回false。例如:
if (!pg_query($cnx, "deallocate foobar")) {
echo "Error deallocate: " . pg_last_error($cnx);
}
else {
echo "deallocate successful";
}
显示:
错误解除分配:错误:准备好的语句“foobar”不存在
请注意,deallocate的语句名称不能用单引号括起来,因为它是标识符,而不是字符串文字。如果由于有问题的字符需要封闭它,可以用pg_escape_identifier
(php> = 5.4.4)
要清理会话,甚至不必迭代准备好的语句并逐个取消分配,您可以改为DEALLOCATE ALL
,而是pg_query
。
还有另一个声明在一个查询中执行更多清理:
DISCARD ALL
此外,如果脚本真的与postgres断开连接,则甚至都不需要这样做,因为预准备语句是其父会话的本地语句并且随之死亡。
在脚本之间使用连接重用时,显式清理是必要的,可以是PHP(pg_pconnect
)的持久连接,也可以是pgBouncer之类的连接池(尽管pooler本身可能会调用DISCARD ALL
根据其配置而定。)
答案 1 :(得分:2)
根本没有必要解除分配。 PostgreSQL在会话结束后立即释放准备好的语句:http://www.postgresql.org/docs/9.3/static/sql-deallocate.html
编辑:尽管您声称它是,但我不明白为什么这对PHP脚本会有所不同。如果您使用池化连接,那么您想要保留准备好的语句,而不是在每次运行脚本时再次编译它们。