tags:

views:

217

answers:

4

I have a function defined inside an Oracle package:

CREATE OR REPLACE PACKAGE BODY TESTUSER.TESTPKG as
  FUNCTION testfunc(n IN NUMBER) RETURN NUMBER as
  begin
    return n + 1;
  end testfunc;
end testpkg;
/

How can I call it from C# using Odbc? I tried the following:

using System;
using System.Data;
using System.Data.Odbc;

class Program {
    static void Main(string[] args) {
        using (OdbcConnection connection = new OdbcConnection("DSN=testdb;UID=testuser;PWD=testpwd")) {
            connection.Open();

            OdbcCommand command = new OdbcCommand("TESTUSER.TESTPKG.testfunc", connection);
            command.CommandType = System.Data.CommandType.StoredProcedure;

            command.Parameters.Add("ret", OdbcType.Int).Direction = ParameterDirection.ReturnValue;

            command.Parameters.Add("n", OdbcType.Int).Direction = ParameterDirection.Input;
            command.Parameters["n"].Value = 42;

            command.ExecuteNonQuery();
            Console.WriteLine(command.Parameters["ret"].Value);
        }
    }
}

But I get an exception saying "Invalid SQL Statement".
What am I doing wrong?

+2  A: 

In the past I would use something like to following for the command string:

"{? = CALL JF_TESTUSER.TESTPKG.testFunc(?)}"

See the following article for more information

Garett
This works as well, thanks.
Paolo Tedesco
A: 

try

OdbcCommand command = new OdbcCommand("begin ? := TESTUSER.TESTPKG.testfunc(?) end;", connection);
ammoQ
A: 

I managed to call the package function like this:

command.CommandText = @"begin
    :ret := ILMTEST.testpkg.testfunc(:n);
end;";
command.CommandType = System.Data.CommandType.Text;
Paolo Tedesco
A: 

I think you should consider using the Oracle Client instead.

And if you choose ODBC to have just to create a DSN and then connect to it to be somehow database agnostic, consider using Enterprise Library Data Access Application Block.

Will Marcouiller
I wanted to avoid using the Oracle Client to avoid the deployment of the extra assemblies; what are the reasons to use Oracle Client?
Paolo Tedesco
First of all, it easily handles the Oracle Package feature. Second, it is optimized for Oracle, so better performances are to be expected when accessing data. Third, because even Microsoft deprecated its System.Data.OracleClient provider which was part of the GAC, thus recognizing somehow, if we may say so, that the `ODP` was best.
Will Marcouiller
I'm not using System.Data.OracleClient provider here, and I managed to do what I needed. I should check about performance, but for the time being it looks like Odbc is enough for me...
Paolo Tedesco