Hi there,
here's a small patch for sybase_query() in ext/sybase_ct.c which gives
some extended functionality in that it allows to send batch queries from
php to the Sybase backend.
Currently it's only possible to send single queries via sybase_query(),
but in some cases it can be convenient to construct SQL batches and send
them as a single sequence of queries to the DB. The only restriction
then is (AFAIK) that, if you want to return a result, it has to be the
last SQL statement in the batch. It can be preceeded by any (reasonable)
number of "preparing" queries, which only return some SUCCEED/FAIL
status.
Here's an example:
$sql ="SELECT id, name INTO #tmp1 FROM person ";
$sql .= INSERT #tmp1 VALUES (some_id, "some_name") ";
$sql .= DELETE FROM #tmp1 WHERE some_condition ";
$sql .= SELECT * FROM #tmp1";
$result_id = sybase_query($query, $conn_id);
Well, if this does not make too much sense ... I hope you get the idea
;-)
I've just adapted the code for 4.3.0, but we've been using this without
any bad experience in production on 4.2.1 for some time now.
I'd like to ask the sybase_ct maintainer, if he sees any conflicts with
the code for sybase_unbuffered_query() that was newly introduced in
4.3.0.
If you think the new functionality is useful, feel free to use it ...
Best regards ... Michael U.
--- php-4.3.0/ext/sybase_ct/php_sybase_ct.c.orig Fri Feb 14 12:45:56 2003
+++ php-4.3.0/ext/sybase_ct/php_sybase_ct.c Fri Feb 14 13:45:32 2003
@@ -1297,6 +1297,7 @@
deadlock_count= 0;
for (;;) {
result = NULL;
+ status = Q_FAILURE;
sybase_ptr->deadlock = 0;
sybase_ptr->affected_rows = 0;
@@ -1322,81 +1323,94 @@
RETURN_FALSE;
}
- /* Use the first result set or succeed/fail status and discard the
- * others. Applications really shouldn't be making calls that
+ /* Use the first result set preceeded by an arbitrary number of
+ * succeed/fail stati from other queries and discard any result
+ * sets following the first.
+ *
+ * Example: Batch Query (may not make too much sense ...)
+ *
+ * SELECT id, name INTO #tmp1 FROM person // returns only status
+ * INSERT #tmp1 VALUES (some_id, "some_name") // " " "
+ * DELETE FROM #tmp1 WHERE some_condition // " " "
+ * SELECT * FORM #tmp1 // returns result set
+ *
+ * Applications really shouldn't be making calls that
* return multiple result sets, but if they do then we need to
* properly read or cancel them or the connection will become
* unusable.
*/
- if (ct_results(sybase_ptr->cmd, &restype)!=CS_SUCCEED) {
- ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_ALL);
- sybase_ptr->dead = 1;
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase: Cannot
read results");
- RETURN_FALSE;
- }
-
- switch ((int) restype) {
- case CS_CMD_FAIL:
- default:
- status = Q_FAILURE;
- break;
- case CS_CMD_SUCCEED:
- case CS_CMD_DONE: {
+
+ while ((retcode = ct_results(sybase_ptr->cmd, &restype)) ==
+CS_SUCCEED) {
+ switch ((int) restype) {
+ case CS_CMD_FAIL:
+ default:
+ status = Q_FAILURE;
+ break;
+ case CS_CMD_SUCCEED:
+ case CS_CMD_DONE: {
CS_INT row_count;
if (ct_res_info(sybase_ptr->cmd, CS_ROW_COUNT,
&row_count, CS_UNUSED, NULL)==CS_SUCCEED) {
sybase_ptr->affected_rows =
(long)row_count;
}
}
/* Fall through */
- case CS_COMPUTEFMT_RESULT:
- case CS_ROWFMT_RESULT:
- case CS_DESCRIBE_RESULT:
- case CS_MSG_RESULT:
- buffered= 0; /* These
queries have no need for buffering */
- status = Q_SUCCESS;
- break;
- case CS_COMPUTE_RESULT:
- case CS_CURSOR_RESULT:
- case CS_PARAM_RESULT:
- case CS_ROW_RESULT:
- case CS_STATUS_RESULT:
- result = php_sybase_fetch_result_set(sybase_ptr,
buffered, store);
- if (result == NULL) {
- ct_cancel(NULL, sybase_ptr->cmd,
CS_CANCEL_ALL);
- sybase_ptr->dead = 1;
- RETURN_FALSE;
- }
- status = Q_RESULT;
+ case CS_COMPUTEFMT_RESULT:
+ case CS_ROWFMT_RESULT:
+ case CS_DESCRIBE_RESULT:
+ case CS_MSG_RESULT:
+ buffered= 0; /*
+These queries have no need for buffering */
+ status = Q_SUCCESS;
+ break;
+ case CS_COMPUTE_RESULT:
+ case CS_CURSOR_RESULT:
+ case CS_PARAM_RESULT:
+ case CS_ROW_RESULT:
+ case CS_STATUS_RESULT:
+ result =
+php_sybase_fetch_result_set(sybase_ptr, buffered, store);
+ if (result == NULL) {
+ ct_cancel(NULL, sybase_ptr->cmd,
+CS_CANCEL_ALL);
+ sybase_ptr->dead = 1;
+ RETURN_FALSE;
+ }
+ status = Q_RESULT;
+ break;
+ }
+ if (status == Q_RESULT) {
break;
+ } else if (status == Q_FAILURE) {
+ ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_ALL);
+ }
}
/* Check for left-over results */
if (!buffered && status != Q_RESULT) {
- while ((retcode = ct_results(sybase_ptr->cmd,
&restype))==CS_SUCCEED) {
- switch ((int) restype) {
- case CS_CMD_SUCCEED:
- case CS_CMD_DONE:
- break;
-
- case CS_CMD_FAIL:
- status = Q_FAILURE;
- break;
-
- case CS_COMPUTE_RESULT:
- case CS_CURSOR_RESULT:
- case CS_PARAM_RESULT:
- case CS_ROW_RESULT:
- /* Unexpected results, cancel them. */
- case CS_STATUS_RESULT:
- ct_cancel(NULL, sybase_ptr->cmd,
CS_CANCEL_CURRENT);
- break;
-
- default:
- status = Q_FAILURE;
- break;
- }
- if (status == Q_FAILURE) {
- ct_cancel(NULL, sybase_ptr->cmd,
CS_CANCEL_ALL);
+ if (retcode != CS_END_RESULTS) {
+ while ((retcode = ct_results(sybase_ptr->cmd,
+&restype))==CS_SUCCEED) {
+ switch ((int) restype) {
+ case CS_CMD_SUCCEED:
+ case CS_CMD_DONE:
+ break;
+
+ case CS_CMD_FAIL:
+ status = Q_FAILURE;
+ break;
+
+ case CS_COMPUTE_RESULT:
+ case CS_CURSOR_RESULT:
+ case CS_PARAM_RESULT:
+ case CS_ROW_RESULT:
+ /* Unexpected results, cancel
+them. */
+ case CS_STATUS_RESULT:
+ ct_cancel(NULL,
+sybase_ptr->cmd, CS_CANCEL_CURRENT);
+ break;
+
+ default:
+ status = Q_FAILURE;
+ break;
+ }
+ if (status == Q_FAILURE) {
+ ct_cancel(NULL, sybase_ptr->cmd,
+CS_CANCEL_ALL);
+ }
}
}
@@ -1422,7 +1436,7 @@
status = Q_FAILURE;
break;
}
- }
+ } // END - if(!buffered && status != Q_RESULT)
/* Retry deadlocks up until deadlock_retry_count times */
if (sybase_ptr->deadlock && SybCtG(deadlock_retry_count) != -1 &&
++deadlock_count > SybCtG(deadlock_retry_count)) {
@@ -1451,7 +1465,7 @@
if (result != NULL) {
_free_sybase_result(result);
}
- }
+ } // END - for(;;)
if (status == Q_SUCCESS) {
RETURN_TRUE;
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php