This is the last post from my 2010 archives. I’m glad to pop these up on to my blog, if only to be able to reference them quickly if I need to mess around with any of these features. Now I’ve got to get cracking and generate some new content!
This is the 2nd blog posting addressing querying SQL Server from Oracle and vice versa. This post covers the vice versa part, from SQL Server to Oracle.
Assuming that SQL Server is working fine on your windows host, the first step is to install the Oracle client on the SQL Server host. Be sure to choose the Windows components, specifically Oracle OLEDB. That’s critical! Then configure the Oracle networking files appropriately for your target system. By this I mean adjusting the tnsnames.ora file if you are hard coding the Oracle database location, or ensuring that you have the correct LDAP.ORA setting if you use OID to look up Oracle locations. Here are some links for help with the if you have not configured Oracle client network files: 11G R2 docs on adjusting tnsnames using Oracle GUI tools, Ora FAQ on editing tnsnames.ora directly, Ora FAQ on editing ldap.ora directly.
Once the Oracle client is correctly configured, try a quick test with TNSPING from the command line to ensure that Oracle client can find the database with the tnsnames.ora or ldap.ora changes you made.
If things are OK at the Oracle client level, you must now restart SQL Server. This is because the Oracle client install updates the system PATH environment variable. The SQL Server service only checks this at startup time, so it needs a restart to get the updated value of PATH in order to find the Oracle client files.
The rest of this article addresses how to enable SQL queries executing within SQL Server to contact the Oracle database using something called a Linked Server. However, know that frequently people make Oracle data available in SQL Server by means of an SSIS job that queries Oracle and loads data into a table. By making a linked server, any sql session with appropriate permissions will be able to use the linked server.
You can create the linked server in T-SQL like this:
EXEC master.dbo.sp_addlinkedserver @server = 'ORA_LINKED_S', @srvproduct='Any string', @provider='OraOLEDB.Oracle', @datasrc='ORA_SID', @provstr='XXX'
In my testing, for Oracle data sources, it seemed that only the provider argument had to be precise in order to specify the OLEDB Oracle driver and the datasrc argument had to match the Oracle name as indicated in TNSNAMES.ORA or your LDAP server. The other values are descriptive for Oracle sources.
Then you need to provide the Oracle login information:
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname='ORA_LINKED_S',@useself='False',@locallogin=NULL,@rmtuser='joe_user',@rmtpassword='joe_pwd'
You can also configure a Linked Server via the SQL Server Management Studio GUI. To do that, connect to your instance with Management Studio, then expand the Instance and then the Server Objects icon. Right click on the Linked Servers icon and select New Linked Server choice. This screen will allow you to input the values needed. Choose the Oracle Provider for OLEDB. You also need to provide the username and password for the user connecting to Oracle.
With the linked server in place, you can now query Oracle from within SQL Server.
Here again you have choices.
To query using native T-SQL, use this syntax:
select * from ORA_LINKED_S..SCHEMA.TABLE_NAME
Yes, that’s two dots before the word SCHEMA. In my testing, I had to do all upper case in order for the query to run. It’s possible if the remote Oracle objects were created with mixed case using quotations that you would have to match that case.
The other choice is to do pass through queries, which enable you to use Oracle SQL syntax that gets parsed at the remote Oracle database. You use the OPENQUERY function to do that.
select * from openquery(ORA_LINKED_S, 'select * from table_name where rownum < 10')
Note that in the above example the case was not important, provided the objects were not created with quotation marks and specific case in Oracle. Also, the above uses an Oracle specific syntax: rownum < 10. That rownum clause won't work in native T-SQL.
Here's a gotcha that we encountered in my shop when having 64-bit SQL Server 2008 running on 64-bit windows and running SSIS jobs that connected to a remote Oracle database. The solution to getting everything working was to install both 32 and 64 bit Oracle clients on the same machine. See this write up from sqlblogcasts.com for more details.