Connect To Oracle Database From Excel VBA - excel

I need to connect to an Oracle database through Excel VBA.
I added the "Micorost ActiveX Data Objects 6.1" library in VBA.
Since I am using 64-bit version of Excel (in a 64-bit Windows 10), I think I cannot use "Microsoft ODBC for Oracle" (which seems to be 32-bit only); that's why I have installed "Oracle InstantClient v21.3" (InstantClient Basic, InstantClient ODBC and InstantClient SDK; all for Windows x64) into "D:\D:\Program Files\Oracle ODBC" and then installed it using the supplied "odbc_install.exe".
I have added that folder to the system PATH and TNS_ADMIN system variable.
My TnsName.ora has the following database definition:
DATAVIEW =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.x.x.x)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = **MyStats**)
)
)
I can connect to that database using "PL SQL" and also whenever I add an entry in Windows 10's "ODBC Data Source Administrator (64-bit)", I can connect to the database. Moreover, using the "Data --> Get Data --> From Other Sources --> From ODBC" option in Excel itself, I can see the "MyStats" database in the list and can connect to it.
I am trying to connect to that database using the below code in Excel VBA:
Dim Database_Connection As ADODB.Connection
Dim Record_Set As ADODB.Recordset
Dim Database_Connection_String As String
Set Database_Connection = New ADODB.Connection
Set Record_Set = New ADODB.Recordset
Database_Connection_String = "Provider=OraOLEDB.Oracle;Data Source=(DESCRIPTION=(CID=GTU_APP)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=10.x.x.x)(PORT=1521)))(CONNECT_DATA=(SID=MyStats)(SERVER=DEDICATED)));User Id=MyName;Password=MyPass;"
With Database_Connection
.ConnectionString = Database_Connection_String
.Open
End With
This runs into different run-time errors (in the ".Open" line).
I tried to supply "Provider=OraOLEDB.Oracle", "Driver=Oracle in Oracle ODBC". I tried TNS-based strings and standalone ones (giving "Data Source=", "Server=", "DBQ=" and ...). I either get run-time error 3706 which is saying the provider is unknown or Runtime-error -2147217805 (80040e73).
I searched a lot of forums and read a lot of examples. They rely on Microsoft ODBC for Oracle (which is what I don't want to use) or get the code to run somehow which I cannot replicate.
Can I give a different "Provider" name in the connection string or driver?
I'd appreciate if you can give me both TNS-based and standalone strings.

Had similar problem, but after long research I was able to resolve it with such connection string:
Dim Cn As New ADODB.Connection
With Cn
.ConnectionString = "Driver={Oracle in instantclient_21_3};" & _
"DBQ=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=<host>)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=<service_name>)));UID=<user_name>; PWD=<password>;"
Call .Open
End With
Please, change <...> values accordingly.

Related

Reference for DB2 access from Excel?

I am having a terrible time trying to get the most simple code to execute consistently in an Excel VBA module.
I'm just trying to assign the value of a field (column) in DB2 to a variable in the module. I've tried the following:
Connection:
Dim odbcName as String
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strCmd As String
'ACME is the name of the ODBC connection I've established and verified/validated.
conn.Open("ACME")
strCmd = "SELECT UNIQUEID, MARKET, SECTOR, CLIENTID FROM PROJECTINFO WHERE UNIQUEID=1234567"
rs.Open Source:=strCmd, ActiveConnection:=conn, CursorType:=adOpenDynamic, LockType:=adLockOptimistic
All is good to that point. The next bit of code is:
If rs.EOF then
'Do some work to add a record if it doesn't already exist - this works fine.
Else
Dim sqlMarket as String
sqlMarket = rs.Fields("MARKET").Value
End If
I also tried:
sqlMarket = rs!MARKET
Both of those attempts, ON THAT LINE where I was attempting to assign a local variable the contents of the MARKET field in the recordset, caused it to crash. I mean, the entire workbook closes, then Excel reopens and tries to open the worksheets, but the module has crashed completely.
Ultimately, my intent is to check all the fields in the recordset against another set of data (in another Excel workbook), and if anything has changed, to update the DB2 recordset. But right now, I can't even seem to LOOK AT the contents of the DB2 recordset without Excel crashing.
Can anyone offer some advice as to what I'm either doing wrong, or what I'm missing?
Excel 365 (Version 1908) 64-bit
IBM DB21085I 64-bit (SQL11050 with level identifier 0601010F)
DB2 v11.5.0.1077
Windows 10 64-bit Version1909 (Build 18363.900)

Connection from VBA to Oracle DB

With setup from text below I successfully connected and retrieve data from DB. One time, while macro was executing, my PC (windows 10) lost the power and from that moment on I'm receiving the error every time I tried to connect to DB (only while I'm trying to connect via VBA) with following message:Run-time error '-2147467259 (80004005)':[Microsoft][ODBC driver for Oracle][Oracle]Error while trying to retrieve text for error ORA-01019Error that I received is from the line with command "cn.Open (strConnection)"I have installed ODAC 12c 32bit because I have Excel 32bit.I think that this error is active because of info from some register which is locked after PC lost the power while retrieving data but I can't find it.Any help or hint will be precious to me.Thanks in advance
Configuration is:Environment Variables:ORACLE_HOME = C:\app\client\xxxx\product\12.2.0\client_1PATH = C:\app\client\xxxx\product\12.2.0\client_1\Network\AdminPATH = C:\app\client\xxxx\product\12.2.0\client_1\Network\Admin\binReferences - VBAProject:Visual Basic for ApplicationsMicrosoft Excel 16.0 Object LibraryMicrosoft Forms 2.0 Object LibraryMicrosoft ActiveX Data Objects 2.8 LibraryMicrosoft ActiveX Data Object Recordset 2.8 LibraryMicrosoft OLE DB Simple Provider 1.5 LibraryOraOLEDB 1.0 Type LibraryActive Services:OracleOraClient12Home1_32bitMTSRecoveryServiceI tried to uninstall Oracle Client and install it again, but with no success. Also I created ORACLE_HOME variable and tried more different variants of connection string and combination of included References but error is still the same.
Dim strConneciton As String
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Set cn = New ADODB.Connection
Set rs = New ADODB.Recordset
strConneciton = "Driver={Microsoft ODBC for Oracle};" & _
"CONNECTSTRING=(DESCRIPTION=" & _
"(ADDRESS=(PROTOCOL=TCP)" & _
"(HOST=xxx.xxxx.xxx)(PORT=1521)" & _
"(CONNECT_DATA=(SERVICE_NAME=xxxxx)));user id=user1;password=1234;")
cn.Open (strConneciton)
If cn.State = adStateOpen Then
cn.Close
MsgBox "Completed!"
Else
MsgBox "Connection failed!"
End If
I've been struggling with the same connectivity error. Here's how it worked for me.
This is an extract of my tnsnames.ora:
#VISUALTIME7 / EX PRODUCTION
VISUALTIME7_DEV=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = XXX.XX.XX.XX)(PORT = XXXX))
)
(CONNECT_DATA =
(SERVICE_NAME = VISUALTIME7)
)
)
This is my vba code:
Sub CopyDataFromDatabase()
Dim Conn As ADODB.Connection
Set Conn = New ADODB.Connection
Dim strCon As String
'DataSource argument according to my tnsnames.ora
strCon = "Provider=OraOLEDB.Oracle;Data Source=VISUALTIME7_DEV;User ID=myUser;Password=myPassword;"
Conn.Open (strCon)
Conn.Close
End Sub
My references in vba project:
Visual Basic For Applications
Microsoft Excel 10.0 Object Library
OLE Automation
Microsoft Office 16.0 Object Library
Microsoft ActiveX Data Objects 6.1 Library
Thanks for answers.I added those locations to the PATH variable, but the problem is the same.With change of a driver (Oracle in OraClient12Home1_32bit - which is correct name in ODBC Data Source Administrator (32bit)), I've got the following error: TNS protocol adapter error.I am able to connect from sqlplus to db, but the problem is when I tried to connect via VBA.#Tim, thanks for that hint, but that is not the problem here, I've checked that before.Finally I finished this with new Connection string as you can see below:strConnection = "Provider=OraOLEDB.Oracle;Data Source=xxx.xxxx.xxx:1521/xxxxx;User ID=user1;Password=1234;"Thanks again.

Oracle 11g ado connection strings for ODBC (not OLEDB) using excel VBA 64 bit (DSN Less and tnsnames)

Please help. I have researched this for hours. I get some parts to work but not others.
What I am trying to do is write all the connection strings in excel VBA to connect to Oracle 11g database. I don't want to set up the User DSN in ODBC Administrator and I don't want to have to maintain a tnsnames.ora file.
I can get this to work for OLEDB connection strings but I believe this is no longer supported by Oracle so I want to use the Oracle ODBC Driver commands only.
This is what I have got to work (which requires a tnsnames.ora file)
DRIVER={Oracle in OraClient11g_home1};DBQ=MyTNSnamesALias;UID=xxxx;PWD=xxxx
I have tried this also but I get a TNS Protocol error
DRIVER={Oracle in OraClient11g_home1};
Server=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=hostname)(PORT=xxxx)))
(CONNECT_DATA=(SERVICE_NAME=xxx)(SERVER=DEDICATED)));UID=xxxx;PWD=xxxx
Other useful information might be that i get my connections to work just fine when I use the DSN name as per the ODBC Administrator.
Any suggestions would be greatly appreciated
Thanks
OLEDB Provider from Oracle (Provider=OraOLEDB.Oracle) is still supported, just the provider from Microsoft (Provider=msdaora) is deprecated. Microsoft recommends to use the Oracle provider.
Microsoft provider msdaora does even not exist for 64 Bit.
I think your connection string for Oracle ODBC must be this (without the line breaks):
Driver={Oracle in OraClient11g_home1};
DBQ=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=hostname)(PORT=xxxx)))(CONNECT_DATA=(SERVICE_NAME=xxx)(SERVER=DEDICATED)));
Pwd=xxxx;
Uid=xxxx
Note, for the Oracle driver you must use DBQ instead of Server.
Server is the attribute for the Microsoft ODBC driver (e.g. Driver={Microsoft ODBC for Oracle})
There are no possibility to connect using Oracle ODBC driver without TNS alias already configured in tnsnames.ora file.
All configuration steps mentioned in Oracle ODBC Driver documentation requires it:
Connecting to DataSource
Configuring theDataSource
Oracle ODBC Driver Configuration Dialog Box
Also in documentation for SQLDriverConnect implementation DBQ parameter noted as required, and passing a name of TNS alias in this parameter is only method to specify server to connect to.
Because it's a common API function used by all clients of Oracle ODBC Driver, there are no possibility that some other interface (COM-object, configuration dialog or something else) may accept different parameters for connection.
There are no such possibility in Oracle Objects for OLE too.
I can't find anything about cancelling of Oracle Provider for OLEDB support.
It has been released as a part of latest version of ODAC: "ODAC 12c Release 4 (12.1.0.2.4)" and this release is a top news topic at related section of Oracle site at the moment.
There are some improvements in latest versions and support for usage from .NET applications.
Also, it works (at least for me):
Const hostName = "server_host"
Const portNo = "1521"
Const srvSID = "ORASERVERSID"
Const usrID = "login"
Const usrPwd = "password"
Sub con_Oracle_OLEDB()
strDriver = "Provider=OraOLEDB.Oracle;"
strParams = "Data Source=(DESCRIPTION=(CID=MyVbaApp)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=" + hostName + ")(PORT=" + portNo + ")))(CONNECT_DATA=(SID=" + srvSID + ")));"
strCon = strDriver + strParams + strUser
' Open the above connection string.
Dim con As Object
Set con = CreateObject("ADODB.Connection")
con.ConnectionString = strCon
con.Open
End Sub
Based on the above, I recommend to stay with OLEDB Provider, just update ODAC to a latest version.
If you don't want to use OLEDB at all, there are a variant with Microsoft ODBC driver("Driver={Microsoft ODBC for Oracle};") with detailed server parameters specification in CONNECTSTRING:
Const hostName = "server_host"
Const portNo = "1521"
Const srvSID = "ORASERVERSID"
Const usrID = "login"
Const usrPwd = "password"
Sub con_Microsoft_ODBC_for_Oracle()
strDriver = "Driver={Microsoft ODBC for Oracle};"
strParams = "CONNECTSTRING=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + hostName + ")(PORT=" + portNo + "))(CONNECT_DATA=(SID=" + srvSID + ")));"
strUser = "UID=" + usrID + ";PWD=" + usrPwd + ";"
strCon = strDriver + strParams + strUser
' Open the above connection string.
Dim con As Object
Set con = CreateObject("ADODB.Connection")
con.ConnectionString = strCon
con.Open
End Sub
Of course, this variant has its own drawbacks. At least, there are a much more probability of support cancellation from Microsoft's side than from side of Oracle.
Thanks for the answer. I was trying to use MSDAORA with 64 bit.
I am using OLEDB as per the example. Except that the oledb example doesn't populate strUser, but the next example does:
strUser = "UID=" + usrID + ";PWD=" + usrPwd + ";"
I am getting an invalid user id password, but I am sending the correct one. This is what I am sending (I replaced the password with xxx for security reasons)
Provider=OraOLEDB.Oracle;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=172.16.23.32)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=rmsuat)));Uid=rms;Pwd=XXX;

classic ASP Microsoft OLE DB Provider for ODBC Drivers error '80004005'

I'm working on migrating an application from an IIS 6 to IIS 7.5 and am running into the weirdest issue:
Microsoft OLE DB Provider for ODBC Drivers error '80004005'
[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified
/Complaints/Login.asp, line 175
Here's the code around line 175:
myConn = getDatabaseConnection()
set rs = Server.CreateObject("ADODB.Recordset")
strSQL = "SELECT * FROM Users WHERE lower(Login) = lower('" & uId & "') and Active = 1"
rs.Open strSQL, myConn, 3, 3
Nothing special going on here...
here's the db method:
function getDatabaseConnection()
Dim strConnection
strConnection = "Driver={SQL Server};Server=server.domain.com;Database=cc;uid=acc;pwd=xxx;"
Set GetDatabaseConnection = Server.CreateObject("ADODB.Connection")
GetDatabaseConnection.CommandTimeout = 60
GetDatabaseConnection.ConnectionTimeout = 60
GetDatabaseConnection.CursorLocation = 3
GetDatabaseConnection.Open strConnection
end function
This seems to work in a similar classic asp application running in the same app pool (.NET 1.1)
I've tried: copy pasting the other app's code, using the connection string in place of the db method (throws 500 of course), changing app pools, google, & as another kick it works great on an IIS 6 server.
I took a look at OLE DB Provider for ODBC Drivers Error "80004005' & my connection string seems correct & my ASP.NET 1.1 app pool can only run in 32-bit mode. The DSNs set up on the previous server aren't relevant either.
I have the application working on IIS 5 on domain A and IIS 6 on domain A, but this 7.5 server is on domain B. Thus I'm using the FQDN. I haven't made any other domain specific changes though. The system uses the above method to authenticate users.
Edit: also tried
strConnection = "dsn=my32bitdsn;uid=xxx;pwd=xxx;"
I've inherited this code and am so so with classic ASP, can anybody help?
Updated code:
Dim strConnection, oConn
'get status
set rs = Server.CreateObject("ADODB.Recordset")
strSQL = "SELECT * FROM Users WHERE lower(Login) = lower('" & uId & "') and Active = 1"
'rs.Open strSQL, myConn, 3, 3
strConnection = "Driver={SQL Server};Server=server.domain.com;Database=cc;uid=acc;pwd=xxx;"
Set oConn = Server.CreateObject("ADODB.Connection")
oConn.CommandTimeout = 60
oConn.ConnectionTimeout = 60
oConn.CursorLocation = 3
oConn.Open strConnection
Set rs = oConn.Execute(strSQL)
Might be just cosmetic change, but might solve that issue as well:
Function getDatabaseConnection()
Dim strConnection, oConn
strConnection = "Driver={SQL Server};Server=server.domain.com;Database=cc;uid=acc;pwd=xxx;"
Set oConn = Server.CreateObject("ADODB.Connection")
oConn.CommandTimeout = 60
oConn.ConnectionTimeout = 60
oConn.CursorLocation = 3
oConn.Open strConnection
Set getDatabaseConnection = oConn
End Function
I'm always afraid that using the function name directly will result in unneeded calls or weird results so got used to the above way.
Second thing is that you assign the connection as non object by not having "Set" which also might cause weird and unexpected problems. Change the line to:
Set myConn = getDatabaseConnection()
Hopefully one of the above will solve that weird problem.
I am not sure if you have already solved this error, but if you would like to try and get it to throw a readable error you can try this as part of the connection string.
Your connection string says the db server is server.domain.com or did you just place that there to replace your companies information?
Give this a try:
dim cn
Set cn=Server.CreateObject("ADODB.Connection")
cn.ConnectionString="Provider=SQLOLEDB.1;Persist Security Info=True;User ID=sa;Initial Catalog=dbName;Data Source=(local) or computername;PWD=;Password=yourpassword;"
on error resume next
cn.Open
if err.number <> 0 then response.Write(err.description)
on error goto 0

Connection string syntax for Classic ADO / ODBC / Oracle 10g EZConnect

I'm trying to connect various VBA projects to an Oracle 10g back end using ADO (2.8) and no TNS. After various attempts, we've decided that the simplest series of steps for a clean installation include:
Set up an Oracle Instant Client
Install the accompanying ODBC driver
(Test the connection using EZCONNECT via SQL Plus)
(Test the connection by creating a Windows DSN)
Everything up to here works fine. Problem is, I cannot figure out the syntax to tell ADO to use the instant client ODBC driver, which appears in my ODBC driver list as "Oracle in MyTest" (no quotes). Using the MSFT ODBC driver with EZConnect as this post suggests does not work any better than it did prior to setting up the instant client (which is to say, not at all). But this post seems to suggest it's possible, without stating exactly how, and connectionstrings.com only tells you what the Data Source portion of the string looks like, i.e.
SomeUser/SomePassword#AServer:PortNumber/InstanceName
Short version: What is the exact syntax of a classic ADO connection string referencing an instant client ODBC driver?
Thanks in advance for your help. Took me a stupid long time to get going with SO...
Similar to 'user1206604's answer - I set up an ODBC connection using ODBC Data Source Administrator (for example's sake we'll name it 'DEMO') and connect like this:
Dim conn As New adodb.Connection
Set conn = New adodb.Connection
connStr = "Provider=OraOLEDB.Oracle;Data Source=DEMO;User Id=yourUserID;Password=yourPassword;"
conn.Open connStr
Dim api As New adodb.Recordset
Set api = New adodb.Recordset
yourQueryString = "SELECT foo FROM bar"
api.Open yourQueryString, conn, adOpenDynamic, adLockReadOnly
'adjust above setting as needed
while not api.EOF
'do interesting stuff here
wend
'clean up resources
api.Close
Set api = Nothing
conn.Close
Set conn = Nothing
The ODBC data source administrator is found (on my machine) in start menu > Programs > Oracle - oraClient10g > Configuration and Migration Tools > Microsoft ODBC Administrator and looks like this:
Try this and replace the values as appropriate:
Set Connection = CreateObject("ADODB.Connection")
blnTest = Connection.Open("Driver={Oracle in instantclient};Dbq=127.0.0.1:1521/SERVICENAMEHERE", "USERNAME", "PASSWORD")
If Oracle in instantclient doesn't work check the HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers registry key to see what the value is for the Oracle Instant Client (there may be a version number appended).
If this still doesn't work for you. Leave a comment with the details of what happened and I'll try to adjust the answer for you.
' Create a connection object.'
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
' Create a recordset object.'
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
' Provide the connection string.'
Dim strConn As String
Dim str As String
'Use the SQL Server OLE DB Provider.'
strConn = "Driver=(Oracle in OraHome92);" & "Data Source=;Uid=;Pwd=;"
'Now open the connection.'
cn.Open strConn
With rs
' Assign the Connection object.'
ActiveConnection = cn
' Extract the required records.'
.Open "SELECT ", cn
End With

Resources