PHP 5.6.0 released

pg_send_query

(PHP 4 >= 4.2.0, PHP 5)

pg_send_query Wysyła zapytanie asynchroniczne

Opis

bool pg_send_query ( resource $identyfikator_połączenia , string $zapytanie )

pg_send_query() wysyła asynchroniczne zapytanie lub zapytania do połączenia określonego przez identyfikator_połączenia. W przeciwieństwie do pg_query(), pozwala wysłać jednorazowo wiele zapytań do PostgreSQL-a, na następnie pobrać wyniki jeden po drugim używając funkcji pg_get_result().

Wykonywanie skryptu nie jest blokowane w czasie wykonywania zapytań. Możesz użyć pg_connection_busy() aby sprawdzić czy połączenie jest nie jest zajęte (np. wykonuje się inne zapytanie). Zapytania mogą zostać przerwane przez użycie funkcji pg_cancel_query().

Tak więc użytkownik może wysłać wiele zapytań jednocześnie, ale nie może ich wysyłać jeśli połączenie jest zajęte. Jeśli zapytanie będzie wysłane gdy połączenie jest zajęte, będzie oczekiwało aż wykona się poprzednie zapytanie i utracone zostaną wszystkie wyniki.

Parametry

identyfikator_połączenia

Identyfikator połączenia do bazy PostgreSQL.

zapytanie

Instrukcja lub instrukcje SQL do wykonania.

Dane w zapytaniu powinny posiadać znaki unikowe.

Zwracane wartości

Zwraca TRUE w przypadku powodzenia, FALSE w przypadku błędu.

Użyj pg_get_result(), aby ustalić wynik zapytania.

Przykłady

Przykład #1 Przykład pg_send_query()

<?php
  $polaczenie_z_baza 
pg_connect("dbname=wydawca") or die("Nie można było się połączyć");

  if (!
pg_connection_busy($polaczenie_z_baza)) {
      
pg_send_query($polaczenie_z_baza"select * from autorzy; select count(*) from autorzy;");
  }
  
  
$wynik1 pg_get_result($polaczenie_z_baza);
  echo 
"Pierwsze wywołanie pg_get_result(): $wynik1\n";
  
$wiersze1 pg_num_rows($wynik1);
  echo 
"$wynik1 ma $wiersze1 wpisów\n\n";
  
  
$wynik2 pg_get_result($polaczenie_z_baza);
  echo 
"Drugie wywołanie pg_get_result(): $wynik2\n";
  
$wiersze2 pg_num_rows($wynik2);
  echo 
"$wynik2 ma $wiersze2 wpisów\n";
?>

Powyższy przykład wyświetli:

Pierwsze wywołanie pg_get_result(): Resource id #3
Resource id #3 ma 8 wpisów

Drugie wywołanie pg_get_result(): Resource id #4
Resource id #4 ma 5 wpisów

Zobacz też:

add a note add a note

User Contributed Notes 6 notes

up
0
moodsey211 at gmail dot com
3 years ago
pg_send_query would not stop your script from executing but it would stop the script from exiting.

Example:

<?php
$con
= pg_connect('dbname=payroll');
pg_send_query('SELECT process_payroll()'); // Where process_payroll is a super long process
?>

You would still need to wait for the query to finish before the any display would be sent to the browser. And surprisingly, unlike pg_query this script would not generate the Maximum execution time error.
up
0
rw burgholzer is name at deq dot virginia dot gov
5 years ago
Regarding the failure to process them all now, then retrieve the results later, I found that all queries would return successfully if I added a further condition to your while loop in the "stack_query()" method.

By adding:
&& (pg_transaction_status($conn) === PGSQL_TRANSACTION_IDLE ) )

Every query executed with no errors.

<?php
$conn
= pg_connect("dbname=dbname host=localhost user=psql ");
if (
$conn === FALSE)
  exit(
"Can't connect to db");

$q = array();
// send some queries
foreach (range(0, 50) as $i)
 
stack_query($q, $conn, "SELECT 'query $i' AS str;");
// receive them
while (true)
  {
   
$left = stack_query($q, $conn);
    echo
"$left left... ";
   
$result = pg_get_result($conn);
    if (
$left == 0 && $result === FALSE)
      break;
   
$row = pg_fetch_assoc($result);
   
// depending on race conditions, you wont get all your original queries here.
   
echo "got $row[str]\n";
  }

function
stack_query(&$queries, $conn, $sql = FALSE)
{
  if (
$sql !== FALSE)
   
$queries[] = $sql;
  while (
count($queries) && !pg_connection_busy($conn)  && (pg_transaction_status($conn) === PGSQL_TRANSACTION_IDLE ) )
   
pg_send_query($conn, array_shift($queries));
  return
count($queries) + (pg_connection_busy($conn) ? 1 : 0);
}
?>
up
0
vincentdephily
8 years ago
Note that if you send a query without calling pg_get_result() for the previous one (supposing it has finished and the connection is not busy), the previous query will get discarded.

See for yourself (tested on php4.4.0, postgres8.0.4, Linux/FreeBSD) :
<?
$conn = pg_connect("dbname=template1 host=localhost user=pgsql");
if ($conn === FALSE)
  exit("Can't connect to db");

$q = array();
// send some queries
foreach (range(0, 500) as $i)
  stack_query($q, $conn, "SELECT 'query $i' AS str;");
// receive them
while (true)
  {
    $left = stack_query($q, $conn);
    echo "$left left... ";
    $result = pg_get_result($conn);
    if ($left == 0 && $result === FALSE)
      break;
    $row = pg_fetch_assoc($result);
    // depending on race conditions, you wont get all your original queries here.
    echo "got $row[str]\n";
  }

function stack_query(&$queries, $conn, $sql = FALSE)
{
  if ($sql !== FALSE)
    $queries[] = $sql;
  while (count($queries) && !pg_connection_busy($conn))
    pg_send_query($conn, array_shift($queries));
  return count($queries) + (pg_connection_busy($conn) ? 1 : 0);
}
?>

You will have to write a higher level of abstraction if you want a "send all queries now, receive them later" behaviour.
up
0
Likeyouover others at hotmail dot com
10 years ago
<?php
// --------- OPEN CONN ---

  
$conn = pg_connect("host='127.0.0.1' dbname='test' user='usertest' password='passtest'");

// --------- OPEN FILE ---

  
$fp = fopen('logo.gif', "r");
  
$buffer = fread($fp, filesize('logo.gif'));
  
fclose($fp);

// --------- CREATE - INSERT OID ---

  
pg_exec($conn, "begin");

  
$oid = pg_locreate($conn);

  
$rs = pg_exec($conn,"INSERT INTO test(tipo, images) VALUES('A1', $oid);");
  
$handle = pg_loopen ($conn, $oid, "w");

  
pg_lowrite ($handle, $buffer);
  
pg_loclose ($handle);

  
pg_exec($conn, "commit");

// --------- OPEN - INSERT OID ---

  
$rs = pg_exec($conn, "SELECT images FROM test WHERE tipo = 'A1';");
  
$row = pg_fetch_row($rs, 0);

  
pg_exec($conn, "begin");
  
$loid = pg_loopen($conn, $row[0], "r");

  
header("Content-type: image/gif");

  
pg_loreadall($loid);
  
pg_loclose($loid);

  
pg_exec ($conn, "commit");

// --------- UNLINK OID ---

  
pg_exec($conn, "begin");

  
$loid = $row[0];
  
pg_lounlink($conn, $loid);

  
pg_exec ($conn, "commit");

// --------- DELETE OID ---

  
pg_exec($conn, "DELETE FROM test WHERE tipo = 'A1';");

// --------- CLOSE CONN ---

  
pg_close();
?>
up
0
Mikewithme at yahoo dot com
10 years ago
Due to a bug, OLD API does not available with PHP 4.2.0 and 4.2.1.

PHP 4.2.2 will support OLD API again and will be kept long enough.

New API will be available PHP 4.2.0 to later versions.
yohgaki at php dot net
19-Jun-2002 04:00
Due to a bug, PHP 4.2.0 and 4.2.1 does not support pg_lo_import() old API. It's fixed in PHP 4.2.2.

BTW, new API will be always available from PHP 4.2.0 to later versions. Older API will be kept long enough, also.
ceco at noxis dot net
15-May-2002 09:08
it works for me (php-4.2.1)

not like this

int pg_lo_import ( string pathname [, resource connection])

but
int pg_lo_import ( resource connection, string pathname )

don't know the reason
up
0
Ron Howard
11 years ago
If there is an error in one of your queries, the queries following it will not get executed, and there will *not* be an error message displayed. The only way I can think of to determine if an SQL error happened is to use pg_trace.

Example:

pg_send_query($connection,
    "SELECT id FROM users;
    SELECT * FROM customers;
     [INVALID-SQL-STATEMENT];
    SELECT name FROM countries;");

while ($result = pg_get_result($connection))
    $results[] = $result;

The $results array will only have two items in it.
To Top