SQL Server 2000 offers an alternative to creating a view. Inline table-valued user-defined functions (UDFs) can give you the same functionality as a parameterized view. You can query UDFs as you would a view, but UDFs can accept parameters, which a view can't. You can create the following UDF:

CREATE FUNCTION fn_oradb_scott_dept (@deptno int)
RETURNS TABLE
AS RETURN (SELECT * FROM oradb..SCOTT.DEPT WHERE deptno
  = @deptno)

When you execute this function instead of querying the view, as follows, the WHERE clause is resolved remotely on the Oracle server:

SELECT * FROM fn_oradb_scott_dept(10)

This approach gives you better performance and reduced network traffic compared with using a view.

Updating Linked Data
Now, consider executing a simple INSERT statement from SQL*Plus. Note that unlike SQL Server, Oracle requires the INSERT INTO syntax in every INSERT statement:

INSERT INTO dept (deptno) values (1);

If you execute a similar query from Query Analyzer, as follows,

INSERT INTO oradb..SCOTT.DEPT (deptno) values (2)

you get the following error message:

Server: Msg 7344, Level 16, State 1, Line 1
OLE DB provider 'MSDAORA' could not INSERT INTO table
'[oradb]..[SCOTT].[DEPT]' because of column 'DNAME'. The
column used the default value.
[OLE/DB provider returned message: Multiple-step operation
generated errors. Check each status value.]

This example illustrates a limitation of the Microsoft OLE DB provider. The DEPT table has three columns: deptno, dname, and loc. The dname and loc columns are nullable, so they shouldn't be necessary in an INSERT statement. The Microsoft provider doesn't properly accommodate nullable columns if they're not supplied in an INSERT statement, but you can use a simple workaround. Specify the nullable columns and give them values:

INSERT oradb..SCOTT.DEPT (deptno,dname,loc) values (2,NULL,NULL)

Also note that when you're inserting data into an Oracle table from SQL Server, you don't need to include INTO. Both the Microsoft and Oracle OLE DB providers add INTO to the INSERT statement they execute on the Oracle server.

Using the Oracle Provider for OLE DB, I created a new linked server named orclprvdr and attempted a linked-server INSERT, as follows:

INSERT orclprvdr..SCOTT.DEPT (deptno) values (3)

This query worked, so you can see that Oracle's provider offers advantages when you're doing linked-query INSERT statements. However, Oracle's provider can't execute an INSERT into a table that contains a column that has a DEFAULT constraint defined on it. Microsoft's provider can execute that INSERT as long as you pass an actual value for the column instead of using the keyword DEFAULT.

Unlike an INSERT statement, an UPDATE statement doesn't have problems with nullable columns. If you're issuing a linked-server UPDATE to Oracle, you don't need to specify the nullable columns if you aren't updating them.

UPDATE oradb..SCOTT.DEPT set deptno = 3 WHERE deptno = 2

If you need to join a SQL Server table to an Oracle table, you're executing a heterogeneous query and you must have a linked server. To construct the following example, I used Data Transformation Services (DTS) to move a copy of the Northwind database's Orders table to the SCOTT schema, changing the default destination of "SCOTT"."Orders" to "SCOTT"."ORDERS". I changed the case here to avoid having to use quoted identifiers when I'm using Oracle tools to refer to the table. Oracle databases can support mixed-case object names, but administration and development of an Oracle database is easier when you use all-uppercase object names. The following query joins the Northwind Employees table to the SCOTT schema's copy of Orders:

SELECT lastname FROM employees e
INNER JOIN oradb..SCOTT.ORDERS o
ON e.employeeid = o.employeeid
WHERE o.orderid = 10248

If your heterogeneous query needs to be inside a transaction, you must have the Microsoft Distributed Transaction Coordinator (MS DTC) service running on your SQL Server. For more information, see the sidebar "Transactions," page 28.

Here's one more way to execute a query when you're using a linked-server definition. SQL Server's OPENQUERY system-defined function passes the query through from SQL Server to Oracle:

SELECT * FROM OPENQUERY (oradb,'SELECT * FROM dept
WHERE deptno = 10')

Using OPENQUERY doesn't incur the overhead of the Oracle metadata lookups that I discuss in the sidebar "Analyzing Linked-Server Queries," page 30. With OPENQUERY, all query processing happens on the Oracle linked server and you avoid the metadata lookups. OPENQUERY performs a linked-server query better, but you can't use it in a heterogeneous query.

OPENROWSET is a pass-through query that doesn't use a linked-server definition. It's similar to OPENQUERY, except that it requires you to provide all connection criteria as input parameters:

SELECT * FROM OPENROWSET ('MSDAORA','Ora817';
'SCOTT';'TIGER',' SELECT * FROM dept 
WHERE deptno = 10')

Linked servers are only for executing queries, but as the sidebar "Executing Stored Procedures Remotely" shows, you can execute a query to execute a stored procedure.

Bear in Mind
Before you can use your linked-server setup effectively, you need to know the differences between Oracle and SQL Server data types. If you're storing historical dates in both Oracle and SQL Server, be aware that Oracle's date data type can store dates back to January 1, 4712 b.c., but SQL Server's datetime data type begins at a.d. January 1, 1753. Additionally, Oracle's date data type has a granularity of 0.01 second and SQL Server's datetime has a granularity of 0.001 second. (For more information about the SQL Server datetime data type, see Kalen Delaney, Inside SQL Server, "Solving the Datetime Mystery," September 2000.) For more information about Oracle data types, go to http://technet.oracle.com. You'll need to register (it's free) to get access to the Oracle documentation.

Sometimes you need to get data from more than one database or even from another database server. And when the other database is Oracle, that task is particularly challenging. Microsoft isn't in the business of providing customer support for Oracle databases, and Oracle isn't in the business of providing customer support for SQL Server. However, linked servers can provide convenient access to Oracle data from SQL Server. Now that you know how to configure and use Oracle linked servers, you can get realtime Oracle data in the SQL Server environment you're comfortable in.

End of Article

Prev. page     1 2 [3]     next page -->



You must log on before posting a comment.

If you don't have a username & password, please register now.

Reader Comments

I liked you article. I have been working with SQL Server and Oracle linked in a production environment for 2 years now. You brought up the interesting use of a UDF for selecting from Oracle.

I find that best performance for Inserts is achieved by the construct of :

INSERT INTO OPENQUERY(ORACLEDB, 'Select ... FROM MYTABLE WHERE 1=2') VALUES ( ... )

What do you think ?

Jason Nunn

What about wrapping a distributed transaction around multiple inserts into Oracle and an update into SQL? The MSDAORO OLEDB Provider seems to hurl upon initiating a distributed transaction around the whole lot.

Any ideas?

Richard M. Bagdonas

excellent

Aleksandar Jovanovic

Nice article, but as I am from Germany I have no clue where to find the PATH environment variable described above.

Would be nice to get help, because I think this is where my problems comes from.

Alex

Fantastic!!! Truly useful. Saved a lot of time and frustration. the details on change in PATH file did the trick.

Thanks a lot.

Samir Shah

I agree with Samir.. The advice on the PATH variable was just what the doctor ordered.. Thanks again!!

garyhampson

Article Rating 5 out of 5

Outstanding article, I've linked multiple SQL Servers before but this time I was able to link to an Oracle 10g database -- good job!

Anonymous User

Article Rating 5 out of 5

In SQL Server I create view like "select * from..." source is from Oracle Table. When I update oracle table struture (like add a column) SQL Server (via Linked Server) doesn't update schema...of course, I try refresh, but no effect... Somebody have an idea ? :) Thanks

Anonymous User

Hi : I am retriving data from a oracle database using sql server linked server.

I found that when I run the query in sql plus (oracle) the query executes within seconds but when I am executing the same query using sql server query analyzer it is taking more than 10 min. What could be the problem.

my query involves inner join on 4 tables with millions of data and distinct and where clause. I get 6 rows with the query I am using.

Anonymous User

Anonymous User above, Any query over a network with joins will take ages. If you join two tables, the number of "reads" is very roughly equal to the total number of rows multiplied together I think. Hence all these reads become network reads so it takes ages. Try creating a view in oracle and querying that instead - that should be quicker. Also if you want to get technical check the join order of the query plan.

Anyway my comments - article is good, however I still can't get it to work. Having changed the path variable does anyone know if I have to restart the SQL server? Cheers Will

Anonymous User

Very nice article. I established successfully connection to Oracle but I am unable to execute Stored Procedure. Any clue why?

Anonymous User

Article Rating 5 out of 5

I have: Oracle 8i and SQL Server 2000. I want to create a link server with a Oracle Database.

First: I try with the OLE DB Provider of Oracle. I think that all the necesary data is ok, because I can see all the tables of the Oracle Database in my SQL Server and I can create views of the tables, but when I do a select of a table with more of 100 register I obtain an error of the controler like: Servidor: mensaje 7399, nivel 16, estado 1, línea 1 El proveedor OLE DB 'OraOLEDB.Oracle' informa de un error. El proveedor no proporcionó información acerca del error.

Second: I try with the OLEDB Provider of Microsoft and I can to create the linked server, but whe I try to create a views of any table of the Oracle Data Base I obtain an error like:

Servidor: mensaje 7399, nivel 16, estado 1, línea 1 El proveedor OLE DB 'MSDAORA' informa de un error. El proveedor no proporcionó información acerca del error.

I execute the register script for my windows 2000 correctly but I obtain this error too.

What is the problem with the two OLE DB Provider? Thanks

dialer_ft

Article Rating 5 out of 5

- SQL Server 2000 & Oracle 10g - Oracle10g Provider for OLE DB Version 10.1.0.4.0

Able to create linked server and view all tables. However, query give Server: Msg 7320, Level 16, State 2, Line 1 Could not execute query against OLE DB provider 'OraOLEDB.Oracle'. OLE DB error trace [OLE/DB Provider 'OraOLEDB.Oracle' ICommandText::Execute returned 0x80040155].

Query is select count(DEPT_CODE) from ORADB..ORADBA.DEPARTMENTS

Have changed the PATH. But still the same error.

What other config did I miss out ? Pls help... Txs.

Anonymous User

Article Rating 3 out of 5

Answer for the last comment. I had the same prob.This one solved it:

Message 3 Error 7302: Could not create an instance of OLE DB provider 'MSDAORA' Make sure that the MSDAORA.dll file is registered correctly. (The MSDAORA.dll file is the Microsoft OLE DB provider for Oracle file.) Use RegSvr32.exe to register Microsoft OLE DB Provider for Oracle. If the registration fails, reinstall Microsoft Data Access Components (MDAC). For more information about MDAC, visit the following Microsoft Developer Network (MSDN) Web site: http://msdn.microsoft.com/data/Default.aspx Note If you use a third-party Oracle provider, and your Oracle provider cannot run outside a SQL Server process, enable it to run in-process by changing the provider options. To change the provider options, use one of the following methods. • Method 1 Locate the following registry key. Then, change the value of the AllowInProcess (DWORD) entry to 1. This registry key is located under the corresponding provider name: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Providers\ProviderName • Method 2 Set the Allow InProcess option directly through SQL Server Enterprise Manager when you add a new linked server. Click Provider Options, and then click to select the Allow InProcess check box.

Anonymous User

Article Rating 5 out of 5

Another comment about last post: i deleted the linked server and add it from begining but this time i did this:

Method 2 Set the Allow InProcess option directly through SQL Server Enterprise Manager when you add a new linked server. Click Provider Options, and then click to select the Allow InProcess check box.

Anonymous User

Article Rating 4 out of 5

See More Comments  1   2