Page 1 of 1
Issue with PB4.xx Database library [PB3.9x, ADO, OCI work!]
Posted: Wed Aug 31, 2011 10:26 am
by gnozal
I have a problem using the PB4.xx Database library.
I was translating an old PB 3.94 program, which uses some database queries (only SELECT).
The database is an ORACLE 11 database, and I use UseODBCDatabase().
Using PB4.xx (from 4.00 to 4.60), I get an error after the first query :
DatabaseError() after DatabaseQuery() wrote:[Microsoft][ODBC driver for Oracle]Impossible d'utiliser le curseur de table de caractères sur join, avec une clause distincte union, intersection ou moins ou sur une série de résultats en lecture seule.
Translation :
DatabaseError() after DatabaseQuery() wrote:[Microsoft][ODBC driver for Oracle]Can not use the character table cursor on join with a separate union clause, intersection or with a series of read-only results.
I can't post the whole code, but here is the query text :
Query sample wrote:Select PLAQUE.NUMERO, to_char(plaque.datec,'DDMMYYYYHH24MISS'), ELEMENT.LIB, CUPULE.X, CUPULE.Y FROM CUPULE,PLAQUE,SECTION,AUTOMATE,ELEMENT WHERE (CUPULE.PLAQUE = PLAQUE.ID) And (PLAQUE.ID = SECTION.PLAQUE)And (SECTION.DIST = AUTOMATE.ID) And (AUTOMATE.ID = ELEMENT.ID) And ((AUTOMATE.NOMEXE= 'xxxxxx') Or (AUTOMATE.NOMEXE= 'yyyyyy')) And (CUPULE.NUMERO = 'xxxxxxxx') ORDER BY PLAQUE.DATEC,PLAQUE.NUMERO ASC
Now, the same code gives the expected results (compared with SQLTalk) using PB3.94.
Furthermore, using Srod's ADOmate_DatabaseQuery() with PB4.51 also works...
So I suppose there might be something wrong with the PB4.xx DatabaseQuery()?
(I am no database nor SQL guru...)
Re: Issue with PB4.xx Database library [PB3.9x or ADO works!
Posted: Wed Aug 31, 2011 10:13 pm
by ABBKlaus
You can try tracing and compare the results.
http://msdn.microsoft.com/en-us/library ... s.85).aspx
BR Klaus
Re: Issue with PB4.xx Database library [PB3.9x or ADO works!
Posted: Thu Sep 01, 2011 8:47 am
by gnozal
Thanks ABBKlaus !
The problem seems to be the SQLSetStmtAttr(SQL_ATTR_CURSOR_TYPE) call with PB4.xx.
Here are the ODBC traces :
PB4.51 wrote:Purebasic0 d98-bd4 ENTER SQLAllocHandle
SQLSMALLINT 3 <SQL_HANDLE_STMT>
SQLHANDLE 003C16C8
SQLHANDLE * 0012FF40
Purebasic0 d98-bd4 EXIT SQLAllocHandle with return code 0 (SQL_SUCCESS)
SQLSMALLINT 3 <SQL_HANDLE_STMT>
SQLHANDLE 003C16C8
SQLHANDLE * 0x0012FF40 ( 0x003c2430)
Purebasic0 d98-bd4 ENTER SQLFreeHandle
SQLSMALLINT 3 <SQL_HANDLE_STMT>
SQLHANDLE 003C2430
Purebasic0 d98-bd4 EXIT SQLFreeHandle with return code 0 (SQL_SUCCESS)
SQLSMALLINT 3 <SQL_HANDLE_STMT>
SQLHANDLE 003C2430
Purebasic0 d98-bd4 ENTER SQLAllocHandle
SQLSMALLINT 3 <SQL_HANDLE_STMT>
SQLHANDLE 003C16C8
SQLHANDLE * 003A2A5C
Purebasic0 d98-bd4 EXIT SQLAllocHandle with return code 0 (SQL_SUCCESS)
SQLSMALLINT 3 <SQL_HANDLE_STMT>
SQLHANDLE 003C16C8
SQLHANDLE * 0x003A2A5C ( 0x003c2430)
Purebasic0 d98-bd4 ENTER SQLSetStmtAttr
SQLHSTMT 003C2430
SQLINTEGER 6 <SQL_ATTR_CURSOR_TYPE>
SQLPOINTER 0x00000002
SQLINTEGER -6
Purebasic0 d98-bd4 EXIT SQLSetStmtAttr with return code 1 (SQL_SUCCESS_WITH_INFO)
SQLHSTMT 003C2430
SQLINTEGER 6 <SQL_ATTR_CURSOR_TYPE>
SQLPOINTER 0x00000002 (BADMEM)
SQLINTEGER -6
DIAG [01S02] [Microsoft][ODBC driver for Oracle]Type de curseur modifié (0)
Purebasic0 d98-bd4 ENTER SQLExecDirect
HSTMT 003C2430
UCHAR * 0x009F6160 [ 408] "Select PLAQUE.NUMERO, to_char(plaque.datec,'DDMMYYYYHH24MISS'), ELEMENT.LIB, CUPULE.X, CUPULE.Y FROM CUPULE,PLAQUE,SECTION,AUTOMATE,ELEMENT WHERE (CUPULE.PLAQUE = PLAQUE.ID) And (PLAQUE.ID = SECTION.PLAQUE)And (SECTION.DIST = AUTOMATE.ID) And (AUTOMATE.ID = ELEMENT.ID) And ((AUTOMATE.NOMEXE= 'xxx') Or (AUTOMATE.NOMEXE= 'xxx')) And (CUPULE.NUMERO = 'x') ORDER BY PLAQUE.DATEC,PLAQUE.NUMERO ASC"
SDWORD 408
Purebasic0 d98-bd4 EXIT SQLExecDirect with return code -1 (SQL_ERROR)
HSTMT 003C2430
UCHAR * 0x009F6160 [ 408] "Select PLAQUE.NUMERO, to_char(plaque.datec,'DDMMYYYYHH24MISS'), ELEMENT.LIB, CUPULE.X, CUPULE.Y FROM CUPULE,PLAQUE,SECTION,AUTOMATE,ELEMENT WHERE (CUPULE.PLAQUE = PLAQUE.ID) And (PLAQUE.ID = SECTION.PLAQUE)And (SECTION.DIST = AUTOMATE.ID) And (AUTOMATE.ID = ELEMENT.ID) And ((AUTOMATE.NOMEXE= 'xxx') Or (AUTOMATE.NOMEXE= 'xxx')) And (CUPULE.NUMERO = 'x') ORDER BY PLAQUE.DATEC,PLAQUE.NUMERO ASC"
SDWORD 408
DIAG [HYC00] [Microsoft][ODBC driver for Oracle]Impossible d'utiliser le curseur de table de caractères sur join, avec une clause distincte union, intersection ou moins ou sur une série de résultats en lecture seule (0)
PB3.94 wrote:"PureBasic26461 e04-504 ENTER SQLAllocHandle
SQLSMALLINT 3 <SQL_HANDLE_STMT>
SQLHANDLE 008C16C8
SQLHANDLE * 0012FF50
"PureBasic26461 e04-504 EXIT SQLAllocHandle with return code 0 (SQL_SUCCESS)
SQLSMALLINT 3 <SQL_HANDLE_STMT>
SQLHANDLE 008C16C8
SQLHANDLE * 0x0012FF50 ( 0x008c2430)
"PureBasic26461 e04-504 ENTER SQLFreeHandle
SQLSMALLINT 3 <SQL_HANDLE_STMT>
SQLHANDLE 008C2430
"PureBasic26461 e04-504 EXIT SQLFreeHandle with return code 0 (SQL_SUCCESS)
SQLSMALLINT 3 <SQL_HANDLE_STMT>
SQLHANDLE 008C2430
"PureBasic26461 e04-504 ENTER SQLAllocHandle
SQLSMALLINT 3 <SQL_HANDLE_STMT>
SQLHANDLE 008C16C8
SQLHANDLE * 008A20FC
"PureBasic26461 e04-504 EXIT SQLAllocHandle with return code 0 (SQL_SUCCESS)
SQLSMALLINT 3 <SQL_HANDLE_STMT>
SQLHANDLE 008C16C8
SQLHANDLE * 0x008A20FC ( 0x008c2430)
"PureBasic26461 e04-504 ENTER SQLExecDirect
HSTMT 008C2430
UCHAR * 0x00EF0A40 [ 408] "Select PLAQUE.NUMERO, to_char(plaque.datec,'DDMMYYYYHH24MISS'), ELEMENT.LIB, CUPULE.X, CUPULE.Y FROM CUPULE,PLAQUE,SECTION,AUTOMATE,ELEMENT WHERE (CUPULE.PLAQUE = PLAQUE.ID) And (PLAQUE.ID = SECTION.PLAQUE)And (SECTION.DIST = AUTOMATE.ID) And (AUTOMATE.ID = ELEMENT.ID) And ((AUTOMATE.NOMEXE= 'xxx') Or (AUTOMATE.NOMEXE= 'xxx')) And (CUPULE.NUMERO = 'x') ORDER BY PLAQUE.DATEC,PLAQUE.NUMERO ASC"
SDWORD 408
"PureBasic26461 e04-504 EXIT SQLExecDirect with return code 0 (SQL_SUCCESS)
HSTMT 008C2430
UCHAR * 0x00EF0A40 [ 408] "Select PLAQUE.NUMERO, to_char(plaque.datec,'DDMMYYYYHH24MISS'), ELEMENT.LIB, CUPULE.X, CUPULE.Y FROM CUPULE,PLAQUE,SECTION,AUTOMATE,ELEMENT WHERE (CUPULE.PLAQUE = PLAQUE.ID) And (PLAQUE.ID = SECTION.PLAQUE)And (SECTION.DIST = AUTOMATE.ID) And (AUTOMATE.ID = ELEMENT.ID) And ((AUTOMATE.NOMEXE= 'xxx') Or (AUTOMATE.NOMEXE= 'xxx')) And (CUPULE.NUMERO = 'x') ORDER BY PLAQUE.DATEC,PLAQUE.NUMERO ASC"
SDWORD 408
Re: Issue with PB4.xx Database library [PB3.9x or ADO works!
Posted: Thu Sep 01, 2011 6:52 pm
by ABBKlaus
Heres an explanation for the errorcodes :
http://msdn.microsoft.com/en-us/library ... l.80).aspx
It seems its only a warning : 01S02 Option value changed
MSDN wrote:The character string value returned for SQLSTATE consists of a two-character class value followed by a three-character subclass value. A class value of 01 indicates a warning and is accompanied by a return code of SQL_SUCCESS_WITH_INFO. Class values other than 01, except for the class IM, indicate an error and are accompanied by a return code of SQL_ERROR. The class IM is specific to warnings and errors that derive from the implementation of ODBC. The subclass value 000 in any class is for implementation defined conditions within the given class. The assignment of class and subclass values is defined by SQL-92.
BR Klaus
Re: Issue with PB4.xx Database library [PB3.9x or ADO works!
Posted: Fri Sep 02, 2011 9:33 am
by gnozal
Thanks Klaus.
It might only be a warning, but it's the only difference.
And the error message mentions a cursor problem, and as far as I understand it SQLSetStmtAttr() changes the cursor type.
I can't use PB's genuine database functions anymore because of this issue, so I thought I mention it.
Anyway, ADOmate works great.
Re: Issue with PB4.xx Database library [PB3.9x or ADO works!
Posted: Fri Sep 02, 2011 2:05 pm
by ABBKlaus
You can try this code from JustinJack
Add the call To SQLSetStmtAttr(SQL_ATTR_CURSOR_TYPE)
And if you get the same errormessage you could make a bugreport about this issue.
viewtopic.php?p=331684
BR Klaus
Re: Issue with PB4.xx Database library [PB3.9x or ADO works!
Posted: Fri Sep 02, 2011 3:19 pm
by gnozal
ABBKlaus wrote:You can try this code from JustinJack
Add the call To SQLSetStmtAttr(SQL_ATTR_CURSOR_TYPE)
And if you get the same errormessage you could make a bugreport about this issue.
viewtopic.php?p=331684
BR Klaus
Thanks, I tried this code.
Code: Select all
dbNum = initDataBase()
If dbNum > 0
If myOpenDataBase(dbNum, "xxxx", "xxxxx", "xxxxxxx")
Debug "Ok"
qry.s = "Select PLAQUE.NUMERO, to_char(plaque.datec,'DDMMYYYYHH24MISS'), ELEMENT.LIB, CUPULE.X, CUPULE.Y FROM CUPULE,PLAQUE,SECTION,AUTOMATE,ELEMENT WHERE (CUPULE.PLAQUE = PLAQUE.ID) And (PLAQUE.ID = SECTION.PLAQUE)And (SECTION.DIST = AUTOMATE.ID) And (AUTOMATE.ID = ELEMENT.ID) And ((AUTOMATE.NOMEXE= 'xxxx') Or (AUTOMATE.NOMEXE= 'xxxx')) And (CUPULE.NUMERO = 'xxxxxxxx') ORDER BY PLAQUE.DATEC,PLAQUE.NUMERO ASC"
*ptr = myDataBaseQuery(dbNum, qry.s, 5000)
Debug *ptr ; = 0
numRecords = RowsFetched( dbNum )
Debug numRecords ; = 0
endDataBaseQuery( dbNum )
myCloseDataBase( dbNum )
EndIf
EndIf
I could connect to the database, and the query returned without error.
However, RowsFetched( dbNum ) = 0 ...?
Re: Issue with PB4.xx Database library [PB3.9x or ADO works!
Posted: Fri Sep 02, 2011 5:43 pm
by ABBKlaus
You have to add a ResultColumn()
Re: Issue with PB4.xx Database library [PB3.9x or ADO works!
Posted: Sat Sep 03, 2011 7:55 am
by gnozal
ABBKlaus wrote:You have to add a ResultColumn()
Doh !
Thanks a lot for your help Klaus !
The following code works as expected (like PB3.94 database library and ADOmate) :
Code: Select all
dbNum = initDataBase()
If dbNum > 0
If myOpenDataBase(dbNum, "xxx", "xxx", "xxx")
Debug "Ok"
qry.s = "Select PLAQUE.NUMERO, to_char(plaque.datec,'DDMMYYYYHH24MISS'), ELEMENT.LIB, CUPULE.X, CUPULE.Y FROM CUPULE,PLAQUE,SECTION,AUTOMATE,ELEMENT WHERE (CUPULE.PLAQUE = PLAQUE.ID) And (PLAQUE.ID = SECTION.PLAQUE)And (SECTION.DIST = AUTOMATE.ID) And (AUTOMATE.ID = ELEMENT.ID) And ((AUTOMATE.NOMEXE= 'xxxx') Or (AUTOMATE.NOMEXE= 'xxxx')) And (CUPULE.NUMERO = 'xxxxxxxx') ORDER BY PLAQUE.DATEC,PLAQUE.NUMERO ASC"
addResultColumn(dbNum, #PB_Database_String, 256)
addResultColumn(dbNum, #PB_Database_String, 256)
addResultColumn(dbNum, #PB_Database_String, 256)
addResultColumn(dbNum, #PB_Database_String, 256)
addResultColumn(dbNum, #PB_Database_String, 256)
*ptr = myDataBaseQuery(dbNum, qry.s, 5000)
Debug *ptr ; Ok !
numRecords = RowsFetched( dbNum )
Debug numRecords ; Ok !
For k = 1 To numRecords
Debug PeekS(rowCol(dbNum, k, 1), 256)
Debug PeekS(rowCol(dbNum, k, 2), 256)
Debug PeekS(rowCol(dbNum, k, 3), 256)
Debug PeekS(rowCol(dbNum, k, 4), 256)
Debug PeekS(rowCol(dbNum, k, 5), 256)
Debug "---"
Next
endDataBaseQuery( dbNum )
myCloseDataBase( dbNum )
EndIf
EndIf
Re: Issue with PB4.xx Database library [PB3.9x or ADO works!
Posted: Tue Oct 25, 2011 12:18 pm
by gnozal
I also tried OCILIB : works as expected, no problems like with the PB genuine database library.
Code: Select all
;
;{ OCI LIB [C Driver for Oracle](http://orclib.sourceforge.net)
;
Import "libocilibw.a" ; libociliba.a = ANSI, libocilibw.a = UNICODE
OCI_Initialize(*ErrorHandler, *LibPath, Mode) As "_OCI_Initialize@12" ; Initialize the OCI library - Returns TRUE on success otherwise FALSE
OCI_ConnectionCreate(Database$, User$, Password$, Mode) As "_OCI_ConnectionCreate@16" ; Create a physical connection to an Oracle database server - Connection handle on success or NULL on failure
OCI_StatementCreate(hConnection) As "_OCI_StatementCreate@4" ; Create a statement object - Returns a statement handle on success otherwise NULL
OCI_StatementFree(hStatement) As "_OCI_StatementFree@4" ; Free a statement and all resources associated to it (resultsets ...)
OCI_ExecuteStmt(hStatement, SQL$) As "_OCI_ExecuteStmt@8" ; Execute a SQL statement or PL/SQL block - Returns TRUE on success otherwise FALSE
OCI_GetResultset(hStatement) As "_OCI_GetResultset@4" ; Retrieve the resultset handle from an executed statement - Returns a resultset handle on success otherwise NULL
OCI_GetColumnCount(hResultSet) As "_OCI_GetColumnCount@4" ; Return the number of columns in the resultset
OCI_FetchNext(hResultSet) As "_OCI_FetchNext@4" ; Fetch the next row of the resultset - Returns TRUE on success otherwise FALSE (empty, last row already fetched, an error occurred)
OCI_GetString_Pointer(hResultSet, ColumnIndex) As "_OCI_GetString@8" ; Return the current string value of the column at the given index in the resultset or NULL if index is out of bounds
OCI_Cleanup() As "_OCI_Cleanup@0" ; Clean up all resources allocated by the library
OCI_ErrorGetOCICode(hError) As "_OCI_ErrorGetOCICode@4" ; Retrieve Oracle Error code from error handle
OCI_ErrorGetString(hError) As "_OCI_ErrorGetString@4" ; Retrieve error message from error handle
EndImport
Procedure.s OCI_GetString(hResultSet, ColumnIndex) ; Return the current string value of the column at the given index in the resultset or '' if index is out of bounds
;
Protected OCI_Result, ReturnValue.s
;
OCI_Result = OCI_GetString_Pointer(hResultSet, ColumnIndex)
If OCI_Result
ReturnValue = PeekS(OCI_Result)
EndIf
;
ProcedureReturn ReturnValue
;
EndProcedure
ProcedureC OCI_ErrorHandler(hError) ; OCI error handler MUST be a ProcedureC !!!
;
Shared OCI_ErrorNumber, OCI_ErrorString.s
If hError
OCI_ErrorNumber = OCI_ErrorGetOCICode(hError)
OCI_ErrorString = PeekS(OCI_ErrorGetString(hError))
OCI_ErrorString = RemoveString(OCI_ErrorString, Chr(10))
EndIf
Debug "+++ OCI ERROR " + Str(OCI_ErrorNumber) + " (" + OCI_ErrorString + ") +++"
;
EndProcedure
;
#OCI_ENV_DEFAULT = 0
#OCI_ENV_THREADED = 1
#OCI_ENV_CONTEXT = 2
#OCI_ENV_EVENTS = 4
#OCI_SESSION_DEFAULT = 0
#OCI_SESSION_XA = 1
#OCI_SESSION_SYSDBA = 2
#OCI_SESSION_SYSOPER = 4
#OCI_SESSION_PRELIM_AUTH = 8
;}
;
;
If OCI_Initialize(@OCI_ErrorHandler(), #Null, #OCI_ENV_DEFAULT)
;
hConnection = OCI_ConnectionCreate("xxx", "xxx", "xxx", #OCI_SESSION_DEFAULT)
If hConnection
;
;
hStatement = OCI_StatementCreate(hConnection) ; Create statement
;
;
TexteSQL$ = "Select PLAQUE.NUMERO, to_char(plaque.datec,'DDMMYYYYHH24MISS'), ELEMENT.LIB, CUPULE.X, CUPULE.Y FROM CUPULE,PLAQUE,SECTION,AUTOMATE,ELEMENT WHERE (CUPULE.PLAQUE = PLAQUE.ID) And (PLAQUE.ID = SECTION.PLAQUE)And (SECTION.DIST = AUTOMATE.ID) And (AUTOMATE.ID = ELEMENT.ID) And ((AUTOMATE.NOMEXE= 'xxxx') Or (AUTOMATE.NOMEXE= 'xxxx')) And (CUPULE.NUMERO = 'xxxxxxxx') ORDER BY PLAQUE.DATEC,PLAQUE.NUMERO ASC"
;
If OCI_ExecuteStmt(hStatement, TexteSQL$)
;
hResultSet = OCI_GetResultset(hStatement)
;
If hResultSet
;
NbColumns = OCI_GetColumnCount(hResultSet)
;
While (OCI_FetchNext(hResultSet))
;
Result$ = ""
For Index = 1 To NbColumns
Result$ + OCI_GetString(hResultSet, Index) + ":"
Next
Debug Result$
;
Wend
;
EndIf
;
Else
;
MessageRequester("ERROR", "SQL error !" + Chr(10) + Chr(10) + "ERROR " + Str(OCI_ErrorNumber) + " (" + OCI_ErrorString + ")", #MB_ICONERROR)
;
EndIf
;
;
OCI_StatementFree(hStatement) ; Free statement
;
;
Else
;
MessageRequester("ERROR", "Could not connect to database !" + Chr(10) + Chr(10) + "ERROR " + Str(OCI_ErrorNumber) + " (" + OCI_ErrorString + ")", #MB_ICONERROR)
;
EndIf
;
;
OCI_Cleanup()
;
;
Else
;
MessageRequester("ERROR", "Could not initialize OCILIB !", #MB_ICONERROR)
;
EndIf
Re: Issue with PB4.xx Database library [PB3.9x, ADO, OCI wor
Posted: Thu Apr 30, 2015 5:42 pm
by Michael42
Just checking back on this topic...
In looking for a native way to integrate Oracle 11g\12c is OCILIB or any other native option available to connect to Oracle databases?
If OCILIB is an option can some please spell it out for mere mortals how to use it?
Whats step 1 (2,3)?
Thanks!