Solving the ROW-00060 Error When Using SSIS with Oracle

SSIS logo

I have built SSIS packages to load data from one Oracle database to another before, but never had I come across this error until recently:

“ROW-00060: Internal error: [dainsert,16] Source: Oracle Destination: Oracle Error Occurred @ after 403k records.”

Initially, I thought that some constraint had been violated on the destination data source – like an attempt at a NULL value being inserted into a NOT NULL column. I ran the package a few times and noticed that the row count was always in the neighborhood of 400k and that the package had run for hours. I thought it odd that so many rows could be inserted with no problem, and so a double- and triple-checked to make certain that the constraints on the source columns were the same as those on the destination ones.

Though there were no clear cut solutions explaining exactly why this error happens, several different people on different fora mentioned that they had overcome this particular error (at different row counts, not always 400k!) by using a connector from Attunity rather than the one that comes with the Oracle Client. Fortunately, this driver is made to work with SSIS and is distributed by Microsoft. This driver not only works with Oracle, but also with Teradata. Choose the version based on the version of SSIS you are using.

Version 2.0 for SQL 2012
Version 3.0 for SQL 2014
Version 4.0 for SQL 2016

After installing the connector into Visual Studio and restarting VS, you should be able to use it by selecting “Oracle Source” and/or “Oracle Destination” from the SSIS Toolbox.

Attunity Oracle Source in SSIS

After setting up the new source and destination connections, I was able to run the SSIS package to completion, loading over five million rows of data in less than an hour!

EF Database First with ASP.NET MVC 5 and Oracle Database 12c

NuGet Package Manager

There is a great article called “EF Database First with ASP.NET MVC” by Tom FitzMacken that is part of Microsoft’s ASP.NET MVC tutorial.

I wanted to create a website using the steps outlined here, except instead of using a SQL Server database (as was presented in the article), I wanted to use an Oracle 12c database. Unfortunately, Oracle was not an option in the list of Data Sources as in the image below:

no Oracle option available
Oracle DB was not an option.

I had the basic Oracle setup on my development server, however, I found that I did not have Oracle Developer Tools for Visual Studio. I installed the 32-bit version and rebooted the server; I have not tested the 64-bit version for this particular project. Also, I changed the .NET Framework from 4.5 to 4.6. (From what I have read, 4.52 is the minimum that will work with the EF 6 / Oracle setup.) Lastly, I installed several NuGet packages:

  1. Official Oracle ODP.NET, Managed Driver
  2. Official Oracle ODP.NET, Managed Entity Framework Driver
  3. Oracle Data Provider for .NET (ODP.NET) Managed Driver
  4. Oracle Rdb Entity Framework Provider
NuGet Package Manager
NuGet Package Manager

I closed and reopened Visual Studio 2013, and reopened the solution I had created. Now, when adding a Model as in step 2 of the article, I had Oracle options in the Data Source list!

an Oracle option is available
Oracle is now an option!

After selecting the Oracle option, you can complete setting up the connection as below. TNS is available as an option; if you use this, the connection string to Oracle must bu set up in your TNSnames file.

Connection Properties dialog box
Select your Oracle schema.

After this is done, you can continue with the linked tutorial above!

Creating a Table on Oracle Database with an Identity Column

Oracle Database logo

UPDATE: I was informed by an Oracle Database expert that starting with Oracle 12c, you can indeed have an identity column, and no trigger or sequence is required. The below post still applies to Oracle 11g and older.

If most of your database experience is with SQL Server (as mine is), you’re probably used to creating tables there with IDENTITY columns. For example:

CREATE TABLE [dbo].[tbl_Example](
	[unique_key] [int] PRIMARY KEY IDENTITY(1,1),
	[AuthUser] [varchar](50) NOT NULL,
	[AccessType] [varchar](50) NOT NULL,
	[SiteGrp] [varchar](50) NOT NULL,
	[Approval] [varchar](1) NULL,
	[EmailAddr] [varchar](50) NULL
);

If you wanted to create a table with the same attributes in Oracle, you must remember that there is no IDENTITY modifier. Instead, you must create a trigger that will fire before an insert to generate the equivalent of the IDENTITY value. However, before creating the trigger, you must create a sequence that will hold the numeric value that will be inserted by the trigger.

The table creation statement above, translated for Oracle usage, would look like this:

CREATE TABLE TBL_EXAMPLE(
	unique_key NUMBER PRIMARY KEY,
	AuthUser VARCHAR(50) NOT NULL,
	AccessType VARCHAR(50) NOT NULL,
	SiteGrp VARCHAR(50) NOT NULL,
	Approval VARCHAR(1) NULL,
	EmailAddr VARCHAR(50) NULL
);

CREATE SEQUENCE "SEQ_EXAMPLE" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1;

CREATE OR REPLACE TRIGGER "TRG_EXAMPLE" BEFORE
  INSERT ON "TBL_EXAMPLE" FOR EACH ROW BEGIN
  SELECT SEQ_EXAMPLE.NEXTVAL INTO :NEW.unique_key FROM DUAL;
END;