php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #15141 ODBC Error Messages
Submitted: 2002-01-21 07:46 UTC Modified: 2002-02-15 12:25 UTC
Votes:4
Avg. Score:3.8 ± 1.6
Reproduced:3 of 3 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (33.3%)
From: cox at idecnet dot com Assigned:
Status: No Feedback Package: ODBC related
PHP Version: 4.1.1 OS: Linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2002-01-21 07:46 UTC] cox at idecnet dot com
The PHP odbc driver doesn't manage errors correctly. Here is the complete explanation the Easysoft team gave me:

From: Martin J. Evans <martin@easysoft.com>
"Tomas V.V.Cox" wrote:
> 
> Hi,
> 
> I'm getting a little bit crazy trying to figure out why I always get the
> same unclear error: "01S02 Option Value Changed" when I do *any* bad
> action. Ie:
> 
> "SELECT * FROM tableThatDoesNotExist"
> "SELECT e FROM phptest" (when the "e" field doesn't exist)
> 
> instead of the native code/mesage. Note, that all works fine if there is
> no "human" error.


> I'm using php 4.1.1, unixODBC 2.0.8 as client and OOB - Access as
> server.
> 
> Thanks for any tip on how to solve this obscure problem.
> 
> Tomas V.V.Cox

01S02 is the ODBC defined State and the text for that state is
"option value changed". PHP does not give you the context of the
diagnostic because PHP ignores SQL_SUCCESS_WITH_INFO when attempting
to change the cursor to a dynamic cursor.

i.e.

the following code in PHPs php_odbc.c causes it:

        if (rc == SQL_SUCCESS) {
                if ((result->fetch_abs = (scrollopts &
SQL_FD_FETCH_ABSOLUTE))) 
{
                        /* Try to set CURSOR_TYPE to dynamic. Driver
will replace this with other
                           type if not possible.
                        */
                        if (SQLSetStmtOption(result->stmt,
SQL_CURSOR_TYPE, SQL_CURSOR_DYNAMIC)
                                == SQL_ERROR) {
                                odbc_sql_error(conn, result->stmt, "
SQLSetStmtOption");
                                SQLFreeStmt(result->stmt, SQL_DROP);
                                efree(result);
                                RETURN_FALSE;
                        }
                }
        } else {
                result->fetch_abs = 0;
        }

As PHP uses SQLError() to get diags and PHP is an ODBC 2.0 app the ODBC
spec says the diags stay in place until they are retrieved. So, what
happens is the above code is executed for each new statement and it
generates an informational diagnostic. Then, at some stage later
when you get an error, PHP pulls the first diag which is the one
above and not the one you want. In order to get the one you want you
will have to:

[1] Add a call to SQLError to the above code if SQLSetStmtOption
    returns SQL_SUCCESS_WITH_INFO - this will clear this diag of
    the ODBC driver (driver manager) stack.
[2] Change PHP to allow odbc_error etc to be called repeatedly
    until all diagnostics are cunsumed and you get the one you want.

Martin
--
Martin J. Evans
Easysoft Ltd, UK
Development

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-01-22 19:11 UTC] kalowsky@php.net
Please try a recent CVS snapshot, a small change has been done to the cursor handling which might change your behavior seen.  
 [2002-02-15 12:25 UTC] kalowsky@php.net
No feedback was provided for this bug, so it is being suspended.
If you are able to provide the information that was requested,
please do so and change the status of the bug back to "Open".


 [2004-01-30 19:08 UTC] bergy at us dot ibm dot com
I'm haveing a similar problem.  I'm seeing the same "Option Value Changed" warning, and by looking at the ODBC code, I see that only one error/message is ever retrieved per attempt.  There are comments in the code (in odbc_sql_error) indicated a couple of loops, with the comment that the loop would be endless for some ODBC drivers.  My environment is PHP 4.3.4 on RedHat Linux, IBM DB2 8.1, using unixODBC 2.2.2 (PHP is configured without the "--with-db2").  In my case, I'm undable to handle the actual error in my code because I cannont retrieve the actual error -- only the warning.

I would suggest modifying the code to loop retrieving errors, but either detect an endless loop (hard), or limit the number of errors returned to some reasonable value (easy -- I would think 5 would be more than enough).
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Tue Oct 20 03:01:23 2020 UTC