PDOStatement 类

(PHP 5 >= 5.1.0, PHP 7, PECL pdo >= 1.0.0)

简介

代表一条预处理语句,并在该语句被执行后代表一个相关的结果集。

类摘要

PDOStatement implements Traversable {
/* 属性 */
readonly string $queryString;
/* 方法 */
bool bindColumn ( mixed $column , mixed &$param [, int $type [, int $maxlen [, mixed $driverdata ]]] )
bool bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )
bool bindValue ( mixed $parameter , mixed $value [, int $data_type = PDO::PARAM_STR ] )
bool closeCursor ( void )
int columnCount ( void )
bool debugDumpParams ( void )
string errorCode ( void )
array errorInfo ( void )
bool execute ([ array $input_parameters ] )
mixed fetch ([ int $fetch_style [, int $cursor_orientation = PDO::FETCH_ORI_NEXT [, int $cursor_offset = 0 ]]] )
array fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array $ctor_args = array() ]]] )
string fetchColumn ([ int $column_number = 0 ] )
mixed fetchObject ([ string $class_name = "stdClass" [, array $ctor_args ]] )
mixed getAttribute ( int $attribute )
array getColumnMeta ( int $column )
bool nextRowset ( void )
int rowCount ( void )
bool setAttribute ( int $attribute , mixed $value )
bool setFetchMode ( int $mode )
}

属性

queryString

所用的查询字符串

Table of Contents

User Contributed Notes

Gino D. 17-Oct-2017 07:01
I don't know why PDOStatement don't return "execution time" and "found rows" so here I created an extended class of PDOStatement with these attributes.

Just have to "setAttribute" of PDO's object to $PDO->setAttribute(\PDO::ATTR_STATEMENT_CLASS , ['\customs\PDOStatement', [&$this]]);

<?php

/**
*
*
*
*/

namespace customs;

/**
*
*
*
*/

final class PDOStatement extends \PDOStatement {

   
/**
    *
    *
    *
    */

   
protected $PDO = null;
    protected
$inputParams = [];
    protected
$executionTime = 0;
    protected
$resultCount = 0;

   
/**
    *
    *
    *
    */

   
protected function __construct(PDO &$PDO) {
       
$this->PDO = $PDO;
       
$this->executionTime = microtime(true);
    }

   
/**
    *
    *
    *
    */

   
final public function getExecutionError(int $i = 2) {
       
$executionError = $this->errorInfo();

        if (isset(
$executionError[$i]))
            return
$executionError[$i];

        return
$executionError;
    }

   
/**
    *
    *
    *
    */

   
final public function getExecutionTime($numberFormat = false, $decPoint = '.', $thousandsSep = ',') {
        if (
is_numeric($numberFormat))
            return
number_format($this->executionTime, $numberFormat, $decPoint, $thousandsSep);
       
        return
$this->executionTime;
    }

   
/**
    *
    *
    *
    */

   
final public function getResultCount($numberFormat = false, $decPoint = '.', $thousandsSep = ',') {
        if (
is_numeric($numberFormat))
            return
number_format($this->resultCount, $numberFormat, $decPoint, $thousandsSep);
       
        return
$this->resultCount;
    }

   
/**
    *
    *
    *
    */

   
final public function getLastInsertId() {
        return
$this->PDO->lastInsertId();
    }

   
/**
    *
    *
    *
    */

   
final public function bindValues(array $inputParams) {
        foreach (
$this->inputParams = array_values($inputParams) as $i => $value) {
           
$varType = is_null($value) ? \PDO::PARAM_NULL : is_bool($value) ? \PDO::PARAM_BOOL : is_int($value) ? \PDO::PARAM_INT : \PDO::PARAM_STR;

            if (!
$this->bindValue(++ $i, $value, $varType))
                return
false;
        }

        return
true;
    }

   
/**
    *
    *
    *
    */

   
final public function execute($inputParams = null) {
        if (
$inputParams)
           
$this->inputParams = $inputParams;

        if (
$executed = parent::execute($inputParams))
           
$this->executionTime = microtime(true) - $this->executionTime;

        return
$executed;
    }

   
/**
    *
    *
    *
    */

   
final public function fetchAll($how = null, $className = null, $ctorArgs = null) {
       
$resultSet = parent::fetchAll(... func_get_args());

        if (!empty(
$resultSet)) {
           
$queryString = $this->queryString;
           
$inputParams = $this->inputParams;

            if (
preg_match('/(.*)?LIMIT/is', $queryString, $match))
               
$queryString = $match[1];

           
$queryString = sprintf('SELECT COUNT(*) AS T FROM (%s) DT', $queryString);

            if ((
$placeholders = substr_count($queryString, '?')) < count($inputParams))
               
$inputParams = array_slice($inputParams, 0, $placeholders);

            if ((
$sth = $this->PDO->prepare($queryString)) && $sth->bindValues($inputParams) && $sth->execute())
               
$this->resultCount = $sth->fetchColumn();
               
           
$sth = null;
        }

        return
$resultSet;
    }
}
?>
luis-m-cardoso at ext dot ptinovacao dot pt 16-Sep-2013 11:53
Solved ;)

<?php

$host
= "yourHost";
$user = "yourUser";
$pass = "yourPass";
$db = "yourDB";

$cursor = "cr_123456";

try
{
 
$dbh = new PDO("pgsql:host=$host;port=5432;dbname=$db;user=$user;password=$pass");
  echo
"Connected<p>";
}
catch (
Exception $e)
{
  echo
"Unable to connect: " . $e->getMessage() ."<p>";
}

$dbh->beginTransaction();

$query = "SELECT yourFunction(0::smallint,'2013-08-01 00:00','2013-09-01 00:00',1::smallint,'$cursor')";

$dbh->query($query);

$query = "FETCH ALL IN \"$cursor\"";

echo
"begin data<p>";

foreach (
$dbh->query($query) as $row)
{
    echo
"$row[0] $row[1] $row[2] <br>";
}

echo
"end data";

?>
rosko at zeta dot org dot au 03-Dec-2009 02:50
There are many references around for returning a refcursor from a pgSQL function using pg_query. All essentially boil down to executing the following single statement (or some variation of it):

 begin; select yourFunction(params...); fetch all in cursorname; commit;

In PDO, this doesn't work because PDO won't allow multiple statements submitted as a single statement (due to SQL injection detection). Instead, try this or similar:

<?php
$sql
= 'select yourFunction(params...)';
$db = new PDO('pgsql:dbname=yourDBname');
$db->beginTransaction();
$cmd = $db->prepare($sql);
if (
$cmd->execute()) {
  if (
$query = $db->query('fetch all in cursorname')) {
    ...
processing...
   
$query->closeCursor();
   
$cmd->closeCursor();
  }
}
$db->commit();
?>