PHP / PostgreSQL:检查准备好的语句是否已经存在

时间:2009-07-28 09:38:58

标签: php postgresql prepared-statement

我将我准备好的陈述创建为:

pg_prepare('stm_name', 'SELECT ...');

今天,在声明两次具有相同名称的预准备语句时,我遇到了一个问题(错误地调用了两次函数):

Warning: pg_prepare() [function.pg-prepare]: Query failed: ERROR: prepared statement "insert_av" already exists in xxx on line 221

所以,作为问题标题,有一种方法来检查是否已经存在具有相同标签的prepare语句,以防万一,覆盖它?

我知道这个错误来自我的错误,只需在我的代码开头声明准备好的语句即可解决,但我想知道是否有解决方案可以更好地控制它们。

修改

在Milen回答之后,非常简单地检查准备好的语句是否已经被使用,只需查询数据库中的表pg_prepared_statements:

try{
    $qrParamExist = pg_query_params("SELECT name FROM pg_prepared_statements WHERE name = $1", array($prepared_statement_name));
    if($qrParamExist){
        if(pg_num_rows($qrParamExist) != 0){
            echo 'parametized statement already created';
        }else{
            echo 'parametized statement not present';
        }
    }else{
        throw new Exception('Unable to query the database.');
    }
}catch(Exception $e){
    echo $e->getMessage();
}

但是,我不认为这是一个很好的解决方案,因为我每次都必须查询数据库。

好的,通常准备好的语句是在脚本的开头声明的,然后才重用,但是,我有一个很好的连接类,我不想在我只使用它们中的3个时声明10个预处理语句

所以,我想我将使用一个简单的PHP数组来跟踪我创建的语句,然后使用isset()函数检查它是否存在或是否需要创建:

try{
    $prepare = pg_prepare('my_stmt_name', "SELECT ...");
    if($prepare){
        $this->rayPrepared['my_stmt_name'] = true;
    }else{
        throw new Exception('Prepared statement failed.');
    }
}catch(Exception $e){
    echo $e->getMessage();
}

3 个答案:

答案 0 :(得分:5)

一种方式(我希望有人会指出一个更简单的方法):

<?
$prepared_statement_name = 'activity1';
$mydbname = '...';

$conn = pg_connect("host=... port=... dbname=... user=... password=...");

$result = pg_query_params($conn, 'SELECT name FROM pg_prepared_statements WHERE name = $1', array($prepared_statement_name));

if (pg_num_rows($result) == 0) {
    $result = pg_prepare($conn, $prepared_statement_name, 'SELECT * FROM pg_stat_activity WHERE datname =  $1');
}

$result = pg_execute($conn, $prepared_statement_name, array($mydbname));
while($row = pg_fetch_row($result)) {
    var_dump($row);
}

答案 1 :(得分:0)

没有在php中尝试这个,但如果这在您的应用程序中是可行的(如果您只需要在一个地方使用该语句而不必通过名称再次“获取”它)您可以尝试准备一个未命名的语句。 http://www.postgresql.org/docs/8.4/interactive/libpq-exec.html说:

PQprepare
...
stmtName可能是“”来创建一个未命名的语句,在这种情况下,任何预先存在的未命名语句都会自动替换;否则如果语句名称已在当前会话中定义,则会出错。
php_pg使用PQprepare,因此这可能对您有用。

答案 2 :(得分:-2)

你为什么要使用准备好的陈述?如果您多次使用相同的语句,它们只会提供性能优势。