Use ADODB Recordset to INSERT Oracle DB - oracle

I am converting some Excel-VBA code that uploaded a DAO recordset to an Access database. My new code uses ADODB objects and needs to push the data to Oracle 12c.
I reviewed some articles, and found a handy equivalency chart here: From-DAO-to-ADO. Using this information I created the following code.
This first bit just loads up the source recordset. No problems here, but published if it's relevant:
Dim CN As New ADODB.Connection, RS As New ADODB.Recordset
Dim SRC_CN As New ADODB.Connection, SRC_RS As New ADODB.Recordset, SRC_CMD As New ADODB.Command
strSQL = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Src_WB_nm & _
";Extended Properties='Excel 12.0 Xml;HDR=NO';"
SRC_CN.Open strSQL
Set SRC_CMD.ActiveConnection = SRC_CN
SRC_CMD.CommandType = adCmdText
SRC_RS.Close
Set SRC_RS = Nothing
strSQL = "SELECT * FROM [" & TableNm & "]"
SRC_CMD.CommandText = strSQL
With SRC_RS
.CursorLocation = adUseClient
.CursorType = adOpenDynamic
.LockType = adLockOptimistic
.Open SRC_CMD
End With
In this segment, I open the destination connection and attempt to open the destination recordset. Thismethodology (AddNew, RS...value = RS.value, RS.Update...) worked when I was in DAO. I expect it may need to be modified somewhat, but its the RS.Open command that I can't get past now.
CN.Open CSTRG
strSQL = "DELETE FROM DFSTOOL.C_QUERYLIST"
Set RS = CN.Execute(strSQL)
Set RS = Nothing
RS.Open "DFSTOOL.C_QUERYLIST", CN, adCmdTable
Do Until SRC_RS.EOF
RS.AddNew
RS.Fields(0).Value = SRC_RS.Fields(0).Value
RS.Update
SRC_RS.MoveNext
Loop
RS.Close
SRC_RS.Close
Set RS = Nothing
Set SRC_RS = Nothing
The error thrown is:
I appreciate any help you can provide!

So happily this was a simple syntax issue. Perhaps I should delete the post, but I'll leave it for now in case it helps anyone else. The equivalency table I referenced noted that the "adCmdTable" is an option in ADO, whereas the equivalent "dbOpenTable" was a type in DAO. Thus, I was required to skip a few fields so that it was in the right location. Other fine-tuning followed and the final iteration works as expected:
RS.Open "DFSTOOL.C_QUERYLIST", CN, adOpenForwardOnly, adLockOptimistic, adCmdTable
Do Until SRC_RS.EOF
RS.AddNew
RS.Fields(1).Value = SRC_RS.Fields(0).Value
RS.Update
SRC_RS.MoveNext
Loop
Thanks for your patience community!

Related

display recordcount

I have the following, but it is not putting the count of records from the query in the MsgBox. Only the RR and the TT.
On Error Resume Next
Dim recordCount2
Set con = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")
con.ConnectionString = "Provider=SQLOLEDB;Integrated Security=SSPI;Persist Security Info=False;Data Source=servername\logon;Initial Catalog=database_name"
con.Open
strQry = "SELECT * FROM smd..table_name (nolock) WHERE CAST(LastRunDate AS DATE) = CAST(GETDATE() AS DATE) AND TableNameKey in ('value1', 'value2')"
Set data = con.Open(strQry)
objRecordset.Open strQuery, adoConnection, adOpenDynamic, adLockOptimistic
recordCount2 = objRecordset.Count
MsgBox "TT " & recordCount2 & "RR"
objRS.Close: Set objRS = Nothing
con.Close: Set con = Nothing
My guess is there's an error that's occurring which is being hidden by On error resume next, and recordCount2 = objRecordset.Count is not actually succeeding. Why do you have On error resume next anyway? Delete that line or comment it out, and your problem should become obvious.
Using On Error Resume Next isn't a "magic bullet". Especially like this quote from #ansgar-wiechers
"Contrary to popular belief it doesn't magically make errors go away."
On Error Resume Next is very useful but needs to be used in the correct context. While it is active any statement that raises an error is handled silently, the statement that raised the error is skipped and the inbuilt Err object is populated with the error details for error trapping.
As others have suggested the first thing you should do when debugging these types of problems is comment out On Error Resume Next then the issues I'm about to highlight you might have found yourself.
In the example above there are a couple of lines that are likely raising errors and being skipped, these are;
Set data = con.Open(strQry)
This statement appears to want to execute the query in strQry but con.Open() is the wrong method for this, the ADODB.Connection is already open it doesn't need opening again. You likely meant (but this is a pure guess);
Set data = con.Execute(strQry)
You don't appear to use data after you try running it so I would in this situation just comment it out for now.
The next is;
objRecordset.Open strQuery, adoConnection, adOpenDynamic, adLockOptimistic
which tries to open the ADO.Recordset using strQuery which doesn't appear to defined and neither is adoConnection you likely meant (again guess work);
objRecordset.Open strQry, con, adOpenDynamic, adLockOptimistic
If this statement raises an error and is skipped the statement
recordCount2 = objRecordset.Count
will itself error because the objRecordset .State will be set to adStateClosed.
After these suggestions you should have something like;
'On Error Resume Next
Dim recordCount2, constr
Set con = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")
constr = "Provider=SQLOLEDB;Integrated Security=SSPI;Persist Security Info=False;Data Source=servername\logon;Initial Catalog=database_name"
con.Open constr
strQry = "SELECT * FROM smd..table_name (nolock) WHERE CAST(LastRunDate AS DATE) = CAST(GETDATE() AS DATE) AND TableNameKey in ('value1', 'value2')"
'Set data = con.Open(strQry)
objRecordset.Open strQry, con, adOpenDynamic, adLockOptimistic
recordCount2 = objRecordset.Count
MsgBox "TT " & recordCount2 & "RR"
objRecordset.Close: Set objRecordset = Nothing
con.Close: Set con = Nothing
Avoid writing code as much as possible by writing only those lines/statements you are absolutely sure of. If you haven't seen a bit of documentation that explains why the statement x is neccessary to solve your problem, leave x off.
Before writing code, read the docs: RecordCount property:
... The cursor type of the Recordset object affects whether the number
of records can be determined. The RecordCount property will return -1
for a forward-only cursor; the actual count for a static or keyset
cursor; and either -1 or the actual count for a dynamic cursor,
depending on the data source. ...
So your plan is:
Open a connection
Get a recordset
Access its .RecordCount
The general skeleton for a VBScript contains:
Option Explicit
It does not contain the evil global OERN.
The database work specific skeleton contains:
Dim oCn : Set oCN = CreateObject("ADODB.Connection")
oCn.Open "DSN=???"
...
oCn.Close
It does not contain distracting Set x = Nothing tails.
For production scripts or test code wrt connection problems, you need to write long/complicated/tailored connection strings; for experimental code wrt small specific database features/problems/surprises a (once-for-all-puzzled-together-with-GUI-support) ODBC/DSN connection is more efficient and less error-prone.
The Recordset should be .Opened to play with the Cursor Type:
oRs.Open "SELECT AddressId FROM Person.Address", oCn, adOpenDynamic
Optional Locking left off (until you have documentary or experimental evidence that Lock Type influences .RecordCount).
If you try to run
Option Explicit
Dim oCn : Set oCN = CreateObject("ADODB.Connection")
oCn.Open "DSN=AdvWork"
Dim oRs : Set oRS = CreateObject("ADODB.Recordset")
oRs.Open "SELECT AddressId FROM Person.Address", oCn, adOpenDynamic
WScript.Echo ".RecordCount:", oRs.RecordCount
oCn.Close
you will be told: Variable is undefined: 'adOpenDynamic'. A bit of further (re)reading and your code will look like
Option Explicit
Const adOpenKeyset = 1
Dim oCn : Set oCN = CreateObject("ADODB.Connection")
oCn.Open "DSN=AdvWork"
Dim oRs : Set oRS = CreateObject("ADODB.Recordset")
oRs.Open "SELECT AddressId FROM Person.Address", oCn, adOpenKeyset
WScript.Echo ".RecordCount:", oRs.RecordCount
oCn.Close
output:
cscript 39519953.vbs
.RecordCount: 19614
and the world is a (little bit) better place.
#Brad Larson and #Ekkehard.Horner.... thanks for the guidance, i too was struggling to get the record count from a recordset using VBS and obtaining some info from the windows SYSTEMINDEX (it kept returning -1).
Setting up the Const adOpenKeyset = 1 and then adding that term to the [recordset.oen "SELECT....", oCn, adOpenKeyset] line made it work!!
you will be told: Variable is undefined: 'adOpenDynamic'. A bit of
further (re)reading and your code will look like
Option Explicit
Const adOpenKeyset = 1
Dim oCn : Set oCN = CreateObject("ADODB.Connection")
oCn.Open "DSN=AdvWork"
Dim oRs : Set oRS = CreateObject("ADODB.Recordset")
oRs.Open "SELECT AddressId FROM Person.Address", oCn, adOpenKeyset
WScript.Echo ".RecordCount:", oRs.RecordCount
oCn.Close
output: cscript 39519953.vbs .RecordCount: 19614 and the world is a
(little bit) better place.

Not returning any result while retrieving data from oracle database using vb6, please help me to locate the error

When i check the result set. record count it returns -1 and while checking the recordset.EOF it returns true, thus the result set does not contain any value.
Dim con As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strSQL
Private Sub cmd_login_Click()
Dim pass As String
con.ConnectionString = "Provider=msdaora;Data Source=localhost;User Id=ams;Password=krishnan;"
con.Open
strSQL = "Select passwrd from ams.login_details where username = 'Admin'"
rs.Open strSQL, con
If Not (rs.EOF) Then
If rs("passwrd") = txt_pass.Text Then
MsgBox rs("passwrd")
End If
End If
rs.Close
con.Close
End Sub
I forget to commit the statements in Oracle Sql Developer that's why not data was fetched from the database, When i executed the commit statement, it's working fine.

Memory issue with query of huge table from Oracle database with ADO in Excel VBA

I need to use VBA to query a big data table (2.000.000 rows and 130 columns) from Oracle database and save it into text file.
The code I am using is the following
Dim DBConnection As ADODB.connection
Dim RecordSet As ADODB.RecordSet
'prepare string for connection
Dim strConnection As String
strConnection = "DRIVER=Oracle in OraClient11g_Home32;SERVER=" & database & " ;UID=" & username & ";PWD=" & password & ";DBQ=" & database & ";"
Set DBConnection = New ADODB.connection
'open connection
With DBConnection
.CommandTimeout = False
.ConnectionString = strConnection
.CursorLocation = adUseClient
.Open
End With
Set RecordSet = New ADODB.RecordSet
RecordSet.Open strSQLQuery, DBConnection, adOpenForwardOnly, adLockReadOnly
Do While RecordSet.EOF = False
str = ""
For x = 0 To RecordSet.Fields.Count - 1
If IsNumeric(RecordSet.Fields(x).Value) Then
dx = RecordSet.Fields(x).Value
str = str & Format(dx, "0.############") & delimiter
Else
str = str & RecordSet.Fields(x).Value & delimiter
End If
Next x
Print #FH, str
RecordSet.MoveNext
Loop
The problem is that probably ADO tries to store in the recordset all the queried data, which will be several GB of data, thus using too much RAM.
I need to find a way to limit the number of rows that are stored in RAM at one time, so that I can download and save as many row as I want without having any issue with the RAM.
I researched but I cannot find anything about this.
Thank you.
May be you should try setting CursorLocation to adUseServer...

Oracle and ADO Query from Excel returns no results

I am having trouble running a query in Excel 2010 VBA code using Oracle OraOLEDB.Oracle Provider.
Certain queries work fine and return results, while others return no results...
I connect as such:
Set DBConnection = New ADODB.Connection
DBConnection.Provider = "OraOLEDB.Oracle"
DBConnection.CursorLocation = adUseClient
DBConnection.ConnectionString = "Data Source=" & TNSName & ";User Id=" & OraUserName & ";Password=" & OraPassWord & ";"
DBConnection.Open
I then try to query:
command2.ActiveConnection = DBConnection
command2.CommandText = "SELECT COL1,COL2,COL3 FROM table(MySchema.MyPackage.MyFunction('Param1'))"
command2.CommandType = adCmdText
Set QueryRecordSet = New ADODB.Recordset
QueryRecordSet.LockType = adLockReadOnly
QueryRecordSet.CursorType = adOpenDynamic
QueryRecordSet.Open command2
command2.Execute
and I get nothing...any ideas?
If I run a simple query like
select * From my_table
it works fine...it seems joins or other more complex queries don't compile??
Additionally, selecting from views does not work.
select * from my_view
Returns nothing
I'm putting this as an answer only because comment formatting doesn't allow me to add code.
Does the stored procedure work if you run it separately via the command object?
command2.CommandText = "MySchema.MyPackage.MyFunction"
command2.CommandType = adCmdStoredProc
command2.Parameters.Refresh
command2.Parameters.Item(1).Value = "Param1"
command2.Execute
Debug.Print command2.Parameters.Item(0).Value
I am not sure this is what you are looking for. I was looking for another answer and I know this works for me.
Set cmdSum = New adodb.Command
With cmdSum
Set .ActiveConnection = oCon
.Properties("PLSQLRSet") = True
.CommandText = "{CALL StoredProc(?,?)}"
.CommandType = adCmdText
.Parameters.Append .CreateParameter(, adVarChar, adParamInput, 10, Format(CDate(sTerm), "mm/dd/yyyy"))
.Parameters.Append .CreateParameter(, adVarChar, adParamInput, 10, Format(CDate(sEff), "mm/dd/yyyy"))
End With
Set Rs = cmdSum.Execute()
For c = 0 To Rs.Fields.Count - 1
Wk.Cells(3, c + 1) = Rs.Fields(c).Name
Next c
I ended up here after an Excel ADO query to Oracle would not work.
Although it states in the questions' comments that you can use ODBC to work-around this, it took me a while to figure out how to get the ODBC connection string working.
Here is an ODBC connection to Oracle that I got working.
dbConn = "ODBC;Provider=OraOLEDB.Oracle;" & _
"Data Source=odbc_connection_name;" & _
"User Id=user_id;" & _
"Password=user_pwd;" & _
"DBQ=tns_name;"
tns_name is what you named your connection within the tnsnames.ora file.
odbc_connection_name is what you named your odbc connection.
Then you can just use this to connect to Oracle using ADO like normal:
cn.Open dbConn
cn.CommandTimeout = 1000
rs.Open sql, cn
Note I also had to increase the CommandTimeout property, as ODBC's default timeout is relatively short.

Populating VB6 Combo box using Resultset data source

How to Populate VB6 Combo box using Result set data source ... Please Help
Dim con As New ADODB.Connection
Dim rs2 As New ADODB.Recordset
con.Open "Provider = sqloledb;Data Source=Server01;Initial Catalog=Naveen; User ID= ****; password= ****; Integrated Security= True"
rs2.Open "Select * from Customers", con, adOpenDynamic
Do While rs2.EOF <> True
Combo2.AddItem (rs2.Fields(0).Value)
rs2.MoveNext
Loop
I'm not sure if it works the same way as in VB.NET so I would suggest that you look the ADODB.Recordset object and add each item to the combobox.
One way to load data from an Access database into a combo box (change the connection string for a different DB):
Dim oDb As New ADODB.Connection
Dim oRS As New ADODB.Recordset
Dim sSql As String
oDb.Open "PROVIDER=Microsoft.Jet.OLEDB.4.0;" _
& "Data Source=C:\Data\MyAccessDB.mdb;Jet"
sSql = "SELECT DISTINCT([LastName]) FROM [Authors] ORDER BY LastName ASC"
oRS.Open sSql, oDB, adOpenForwardOnly, adLockReadOnly
Do While not oRS.EOF
With cboMyCombo
.AddItem trim$(oRS("LastName").Value)
End With
oRS.MoveNext
Loop
oRS.Close
oDB.Close
Set oRS = Nothing
Set oDB = Nothing

Resources