我有一个PHP脚本,可以在Postgres DB中插入一行。它在我的测试服务器上运行正常(Postgres 9.1),但在我的新共享主机上失败了(Postgres 8.4)。
$query = "INSERT INTO " . $table . " VALUES (DEFAULT, $1, $2, CURRENT_TIMESTAMP::TIMESTAMP(0), $3, $4, ST_Point($4, $3))";
$result = pg_send_query_params($dbconn, $query, array($is_happy, $rate, $lat, $lon));
$result
始终为TRUE,但未插入任何行。
我也尝试过:
$result = pg_get_result($dbconn);
但经历了同样的行为。
按照@ CraigRinger的交易建议,我也试过了两个:
$query = "BEGIN;INSERT INTO " . $table . " VALUES (DEFAULT, $1, $2, CURRENT_TIMESTAMP::TIMESTAMP(0), $3, $4, ST_Point($4, $3));COMMIT;";
$result = pg_send_query_params($dbconn, $query, array($is_happy, $rate, $lat, $lon));
和
pg_send_query($dbconn, "BEGIN;");
$query = "INSERT INTO " . $table . " VALUES (DEFAULT, $1, $2, CURRENT_TIMESTAMP::TIMESTAMP(0), $3, $4, ST_Point($4, $3));";
$result = pg_send_query_params($dbconn, $query, array($is_happy, $rate, $lat, $lon));
pg_send_query($dbconn, "COMMIT;");
仍然有同样的行为。
如果我在phpPgAdmin中运行INSERT查询,则会插入一行。我也可以在PHP脚本中获得此查询的结果:
"SELECT relid FROM pg_stat_user_tables"
当INSERT查询结果为true但没有插入行时,这意味着什么?可能是什么问题以及我如何解决这个问题?
修改
我可以使用phpPgAdmin INSERT
行,然后使用PHP脚本中的SELECT
行。
这是一个完整的PHP脚本失败(它在我的完整脚本中删除了POST收集和验证)。 rest.php
脚本只保存连接变量和响应函数。此rest.php
脚本适用于我的SELECT
脚本:
<?php
require "KLogger.php";
require "rest.php";
ini_set("error_reporting", E_ALL ^ E_NOTICE);
ini_set("display_errors", 0);
ini_set("log_errors", 1);
$log = KLogger::instance(dirname(__FILE__), KLogger::DEBUG);
$log_id = "AM".time();
$log->logInfo($log_id . " *** " . $_SERVER['REMOTE_ADDR']);
$lat = '51.510199';
$lon = '-0.129654';
$rate = '10';
$is_happy = 't';
$dbconn = pg_connect("host=" . $host . " dbname=" . $db . " user=" . $user . " password=" . $pw);
if(!$dbconn)
{
$log->logInfo($log_id . " No connection: " . pg_last_error());
sendResponse(500, "Internal Server Error");
}
else
{
$query = "INSERT INTO " . $table . " VALUES (DEFAULT, $1, $2, CURRENT_TIMESTAMP::TIMESTAMP(0), $3, $4, ST_Point($4, $3));";
$result = pg_send_query_params($dbconn, $query, array($is_happy, $rate, $lat, $lon));
if(!$result)
{
$log->logInfo($log_id . " No Result: " . pg_last_error());
sendResponse(500, "Internal Server Error");
}
else
{
$log->logInfo($log_id . " sendResponse(200)");
sendResponse(200, "OK");
}
}
pg_close($dbconn);
?>
答案 0 :(得分:2)
此类问题的最常见原因是未公开的交易。
如果你BEGIN
(或者通过在数据库驱动程序中关闭自动提交来隐式执行)然后做一些工作,只有完成工作的事务才能看到更改,直到它COMMIT
。 / p>
如果是这种情况,那么使用相同连接的同一脚本内的立即后续查询将看到更改的行,但没有其他内容。
您还可以通过启用以下内容来检查:
log_statement = 'all'
log_line_prefix = 'db=%d pid=%p vtxid=%v txid=%x'
通过查找vtxid
且无匹配BEGIN
的虚拟交易ID(COMMIT
)来查找不匹配的交易。
如果您无法修改postgresql.conf
,因为它是共享托管,您应该能够ALTER USER myuser SET log_statement = 'all';
或ALTER DATABASE mydatabase SET log_statement = 'all';
。您无法在log_line_prefix
之外设置postgresql.conf
,但您的主机可能已经设置了合理的设置。
另一种可能性 - 可能由版本差异解释的一种可能性 - 是您通过使用9.1中仅提供的功能在事务中稍后触发错误,并且您没有检测到该错误。您之前的INSERT
成功,但是当后面的语句失败时,整个事务将被回滚。再次,检查服务器日志以查看。
另一个常见原因是,当您测试是否插入脚本时,您使用脚本连接的数据库与连接到的脚本不同。插入后,尝试SELECT
您希望从脚本中插入的行。同样值得通过管理工具创建一个虚拟表(在你的情况下似乎是phpPgAdmin),然后测试以查看脚本是否可以看到虚拟表。