0

Using the OracleClient that comes with ADO.NET in .NET Framework, I'm trying to call OracleCommandBuilder.DeriveParameters() method on a procedure in the database, but I keep getting an OracleException with the message: ORA-06564: object CustOrdersOrders does not exist, even though I created the procedure successfully. I'm more familiar with SQL Server, so perhaps I'm missing something here.

SQL

file 1:

create or replace PACKAGE PKGENTLIB_ARCHITECTURE
IS
TYPE CURENTLIB_ARCHITECTURE IS REF CURSOR;
END PKGENTLIB_ARCHITECTURE;
/

file 2

CREATE OR REPLACE PROCEDURE "CustOrdersOrders"(VCUSTOMERID IN Orders.CustomerID%TYPE := 1, CUR_OUT OUT PKGENTLIB_ARCHITECTURE.CURENTLIB_ARCHITECTURE)
    AS

BEGIN
    OPEN cur_OUT FOR
    SELECT
        OrderID,
        OrderDate,
        RequiredDate,
        ShippedDate
    FROM Orders
    WHERE CustomerID = vCustomerId;
END;
/

Both these files were executed in SQL*Plus as @"path\to\file1.sql".

Code

This is using the Enterprise Library Data Access Application Block, which ultimately wraps the ADO.NET API.

DatabaseProviderFactory factory = new DatabaseProviderFactory(...); //this gets a custom configuration source
Database db = factory.Create("OracleTest");
DbCommand storedProcedure = db.GetStoredProcCommand("CustOrdersOrders");
DbConnection connection = db.CreateConnection();
connection.Open();
storedProcedure.Connection = connection;
db.DiscoverParameters(storedProcedure); //this ultimately calls OracleCommandBuilder.DeriveParameters(), which throws the exception.

When I run direct SQL queries using the same connection, they succeed.

More Details

This is actually part of unit tests written for the Data Access Application Block, which I forked here in an attempt to revive this library. That's why it's using the System.Data.OracleClient and not the ODP.NET. The entire set of tests at https://github.com/tsahi/data-access-application-block/blob/master/source/Tests/Oracle.Tests.VSTS/OracleParameterDiscoveryFixture.cs breaks in a similar way.

The tests are running on an Oracle Database XE I installed locally.

Update

Following question by @madreflection, yes, the following code runs correctly:

Database db = DatabaseFactory.CreateDatabase("OracleTest");
string spName = "AddCountry";
DbCommand dbCommand = db.GetStoredProcCommand(spName);
db.AddInParameter(dbCommand, "vCountryCode", DbType.String);
db.AddInParameter(dbCommand, "vCountryName", DbType.String);
db.SetParameterValue(dbCommand, "vCountryCode", "UK");
db.SetParameterValue(dbCommand, "vCountryName", "United Kingdom");

db.ExecuteNonQuery(dbCommand);

using (DataSet ds = db.ExecuteDataSet(CommandType.Text, "select * from Country where CountryCode='UK'"))
{
    Assert.IsTrue(1 == ds.Tables[0].Rows.Count);
    Assert.AreEqual("United Kingdom", ds.Tables[0].Rows[0]["CountryName"].ToString().Trim());
}

where "AddCountry" is defined as

CREATE OR REPLACE PROCEDURE ADDCOUNTRY
(vCountryCode IN Country.CountryCode%TYPE,
 vCountryName IN Country.CountryName%TYPE
)
AS
BEGIN
    INSERT INTO Country (CountryCode,CountryName)
    VALUES (vCountryCode,vCountryName);
END;
/

It's interesting to note, though, that in this case the OracleDatabase pointed by db has in it's packages list just EntlibTest, defined (if I understand correctly) by

CREATE OR REPLACE PACKAGE EntlibTest AS

PROCEDURE GetProductDetailsById
(vProductID IN NUMBER,vProductName OUT VARCHAR2,vUnitPrice OUT NUMBER);

END EntlibTest;
/

and then there is another file defining the body of this procedure with

CREATE OR REPLACE PACKAGE BODY EntlibTest AS

PROCEDURE GetProductDetailsById
(vProductID IN NUMBER,vProductName OUT VARCHAR2,vUnitPrice OUT NUMBER)
AS

BEGIN
    SELECT ProductName,UnitPrice INTO vProductName,vUnitPrice FROM Products where ProductId = vProductId;
END;

END EntlibTest;
/
Tsahi Asher
  • 1,767
  • 15
  • 28
  • Do you have the same problem with procedures created the same way that don't use user-defined types like `.PKGENTLIB_ARCHITECTURE.CURENTLIB_ARCHITECTURE`? – madreflection Jul 02 '20 at 22:54
  • @madreflection see update – Tsahi Asher Jul 03 '20 at 19:30
  • Your example of code that works correctly doesn't use `db.DiscoverParameters` so you've introduced a new variable (test setup variable, not program identifier variable). Is the problem with `db.DiscoverParameters` or is it related to the user-defined type? You can't tell yet because you changed *both* aspects. You need to isolate the problem by changing only one thing at a time and testing. Can you provide an example that calls `db.DiscoverParameters` and doesn't use a user-defined type? – madreflection Jul 04 '20 at 03:10
  • @madreflection it's true that the working example doesn't use `db.DiscoverParameters`, but it does identify the procedure and executes it. I'll try to make a call to `db.DiscoverParameters` on a procedure without user defined types and see what happens. – Tsahi Asher Jul 04 '20 at 13:40
  • I'll post a new question without the DAAB around it, to make it simpler. – Tsahi Asher Jul 04 '20 at 17:28
  • https://stackoverflow.com/questions/62732305/oraclecommandbuilder-deriveparameters-throws-oracleexception-ora-06564-objec – Tsahi Asher Jul 04 '20 at 17:30

0 Answers0