Visual Basic Q&A

As a software engineer, I focus on .NET, especially asp.net, C#, WCF and so on, and I am also very interested in Search Engine Optimization.

Entries Tagged ‘microsoft odbc’

PRB: Error When You Create SQL Server TEMP Tables Using Remote Data Objects (RDO)

Symptoms
When you create a SQL Server local temporary table using the rdoConnection object by calling its .Execute method with default parameters, and then attempt to access the table after the Remote Data Objects (RDO) method has run, you may receive one of the following error messages:

Run-time error ‘40002′: 37000:[Microsoft][ODBC SQL Server Driver][SQL Server] Statement(s)could not be prepared
-or-

Run-time error ‘40002′: S0002:[Microsoft][ODBC SQL Server Driver][SQL Server] Invalid Object Name ‘#<Name of the temporary table>’
Resolution
The creation and use of temporary database tables to facilitate the storage and manipulation of volatile intermediate data is a common programming practice. The default behavior of the SQL Server Open Database Connectivity (ODBC) driver is to create and use temporary stored procedures to run prepared statements. The .Execute method of the rdoConnection object uses the SQLPrepare() and SQLExecute() ODBC application programming interface (API) calls by default to run a SQL statement as a prepared statement. Temporary tables that are created by a stored procedure are automatically dropped when the procedure completes execution. As a result, when you attempt to access a SQL Server temporary table that was created by calling the .Execute method of an rdoConnection object with default parameters, in subsequent statements you receive one of the error messages specified in the “Symptoms” section.

PRB: Client-Side ADO Union Query Using Oracle OLE DB Provider Returns Incorrect Number of Columns

Symptoms
When you create a recordset with ADO 2.5 that contains a Union Query, client-side cursors and the Microsoft Oracle OLE DB Provider return an incorrect number of columns.
This problem does not occur if you use the OLE DB Provider for ODBC Drivers and the Microsoft ODBC for Oracle Drive.
Resolution
Microsoft has confirmed that this is a problem in the Microsoft products that are listed at the beginning of this article.

PRB: “Operation Must Use an Updateable Query” Error Message When You Access Excel Through ODBC

Symptoms
When you edit an Excel worksheet through ADO and ODBC, you may receive the following error message if you use an ADO DataControl object:

[Microsoft][ODBC Excel Driver] Operation must use an updateable query.If you use a Recordset object that is generated with ADO code, you may receive the following error message when you edit an Excel worksheet through ADO and ODBC:

Run-time error ‘-2147467259(80004005)’:[Microsoft][ODBC Excel Driver] Operation must use an updateable query.
Resolution
This problem occurs if you try to edit a worksheet that is saved or opened as ReadOnly.
NOTE: ReadOnly is the default setting for an ODBC connection to Excel, with or without a data source name (DSN). Therefore, the user must always change that setting to edit data.

How To Implement Nested Transactions with Oracle

Symptoms
ADO and ODBC do not support nested transactions. However, native Oracle SQLsupports the SAVEPOINT keyword that can be used to simulate nestedtransactions.
Resolution
The Microsoft Knowledge Base article 177138?(http://support.microsoft.com/kb/177138/EN-US/), entitled “INFO: NestedTransactions Not Available in ODBC/OLE DB/ADO” says this about nestedtransactions:
“Neither Open Database Connectivity (ODBC, nor any released MicrosoftOLE DB Provider supports Nested Transactions. ActiveX Data Objects (ADO)supports the feature, but only if the underlying provider exposes it.Currently none of Microsoft’s OLE DB providers support NestedTransactions.”
This is true for the Microsoft ODBC for Oracle driver. However, by usingthe SAVEPOINT keyword, you can simulate Nested Transactions. For moreinformation about native ODBC or ADO support for Nested Transactions,please see the article mentioned above.
The SAVEPOINT keyword basically sets a bookmark for uncommitted statementsin an Oracle session. You can rollback these statements by using the TOoption with the ROLLBACK statement. This all has to be done through Executestatements (such as in the form of <connection>.Execute) because the ODBCparser cannot parse the SAVEPOINT keyword properly.
The following code shows how this all works:

Conn = “UID=****;PWD=****;DRIVER={Microsoft ODBC for Oracle};” _& “SERVER=SamOracle;”Set Cn = New ADODB.ConnectionWith Cn.ConnectionString = Conn.CursorLocation = adUseClient.OpenEnd WithCn.BeginTransCn.Execute “SAVEPOINT ALPHA”Cn.Execute “INSERT INTO trantest VALUES(1,10)”Cn.Execute “INSERT INTO trantest VALUES(2,10)”Cn.Execute “SAVEPOINT BETA”Cn.Execute “INSERT INTO trantest VALUES(3,10)”Cn.Execute “INSERT INTO trantest VALUES(4,10)”Cn.Execute “ROLLBACK TO SAVEPOINT BETA”Cn.Execute “COMMIT”Cn.RollbackTrans NOTE: This assumes a table “Trantest” exists on the Oracle server.
This code will commit the first two INSERT statements and rollback thesecond two. You will notice that the whole set of statements is surroundedwith a CONNECTION level BeginTrans and CommitTrans. This is necessary sothat, at the ODBC API level, the SQLSetConnectOption SQL_AUTOCOMMIT is setto SQL_AUTOCOMMIT_OFF. After you have finished your transaction it is agood idea to re-set SQL_AUTOCOMMIT to SQL_AUTOCOMMIT_ON (the default) byexecuting either a CommitTrans or a RollbackTrans. Because you have eithercommitted or rolled backed your transactions with your Execute statements,it doesn’t matter whether you call CommitTrans or RollbackTrans; eitherway, they have nothing to commit or rollback. You are just calling thesefunctions to reset SQL_AUTOCOMMIT to SQL_AUTOCOMMIT_ON, which they both do.

How To Extract Multiple RDO Resultsets from Stored Procedures

Symptoms
SQL Server stored procedures are capable of returning more than one recordset and the Remote Data Object (RDO) has the ability to access these Multiple Resultsets.
When calling these stored procedures, the following error can be encountered:

Error 40002
“37000: [Microsoft][ODBC SQL Server Driver][SQL Server]Cannot open a cursor on a stored procedure that has anything other than a single
select statement in it” The following code sample showing how to return the multiple Resultsets using the MoreResults Property of the RDO.
Resolution
There are two methods to avoid Error 40002.
Method 1 Use The ODBC Cursor library rather than Server Side Cursors. To do this, use the following code:

rdoEngine. rdoDefaultCursorDriver = rdUseODBC
- or -

rdoEnvironments(0).CursorDriver = rdUseOdbc This option gives better performance for small result sets, but may degrade quickly for larger result sets depending on the Server and workstation configuration.
NOTE: If you are using SQL text fields, you must use Server-side cursors to bypass Error 40002″

Method 2 Use Server Side Cursors, a Forward Only Cursor, and a rowset size of 1. Make the server create a cursor-less resultset on the server side by using a forward only cursor and a RowSetSize of 1.
The following code sample illustrates how to create a stored procedure that returns multiple result sets using method 2. Create the stored procedure on SQL Server:
Start the ISQL utility that shipped with SQL server. Connect to your SQL server. Select the pubs database from the combo box labeled DB. Enter the following lines into the Query Tab:

CREATE PROCEDURE TestMultiResults ASselect * from authorsselect * from discountsGO Choose the Query|Execute menu. The Results tab should display:
This command did not return data, and it did not return any rows
A stored procedure called TestMultiResults has now been created in the pubs database on SQL Server. Create the Visual Basic client to call the stored procedure:
Start Visual Basic. Form1 is created by default. Add a Command Button (Command1) and a List Box (List1) to Form1. Add the following code to Form1:

Private Sub Form_Load()Command1.Caption = “Run Stored Procedure”End SubPrivate Sub Command1_Click()Dim cn As rdoConnectionDim ps As rdoPreparedStatementDim rs As rdoResultsetDim strConnect As String’set cursor driver to use server-side cursorsrdoDefaultCursorDriver = rdUseServer’open a connection to the pubs database using DSNless connections’Remember to change the following connection string parameters to reflect the correct valuesstrConnect = “Driver={SQL Server}; Server=myServer; ” & _”Database=pubs; Uid=<username>; Pwd=<strong password>”Set cn = rdoEnvironments(0).OpenConnection(dsName:=”", _Prompt:=rdDriverNoPrompt, _ReadOnly:=False, _Connect:=strConnect)’create a prep stmt for the stored proc callSet ps = cn.CreatePreparedStatement(“MyPs”, _”{call TestMultiResults}”)’set the RowSet size to 1ps.RowsetSize = 1′open the resultset with forward-only cursorSet rs = ps.OpenResultset(rdOpenForwardOnly)’add the first resultset to a list boxWhile Not rs.EOFlist1.AddItem rs(“au_fname”) & ” ” & rs(“au_lname”)rs.MoveNextWend’move to the second resultsetrs.MoreResultslist1.AddItem “Second Resultset Below”‘add the second resultset to the same list boxWhile Not rs.EOFlist1.AddItem rs(“discounttype”) & ” = ” & rs(“discount”)rs.MoveNextWend’Close the resultset and the connection and set both to nothingrs.CloseSet rs = Nothingcn.CloseSet cn = NothingEnd Sub Run the project and click the “Run Stored Procedure” button. You should see a list of Authors and then Discounts in the list box.

BUG: AbsolutePosition Property Returns Different Results

Symptoms
When you use the Remote Data Objects (RDO) version 2.0 in either VisualBasic 5.0 or Visual Basic 6.0, with an Oracle 7.x or 8.x database, usingthe Microsoft ODBC for Oracle driver, the AbsolutePosition property of therdoResultset object produces different results depending on the Cursorlocation as set by the CursorDriver property of the rdoConnection orrdoEnvironment object.
Using the rdUseServer cursor library, the AbsolutePosition property reportsthe last row in the Resultset. When tested a second time it returns thecorrect results based on its setting.
If you use either the rdUseODBC or rdUseClientBatch cursor libraries, theresults returned will always be correct.
NOTE: This code has also been tested against Microsoft SQL Server withouterror.
Resolution
The workaround is to use a MoveLast on the Recordset or not to use theCursorDriver properties of rdUseServer or rdUseIfNeeded when the results ofthe AbsolutePosition property must be accurate. The CursorDriver propertiesof rdUseOdbc and rdUseClientBatch produce accurate AbsolutePositionproperty results.