[Oracle g11 + C#] Jak pobrać wartość zwracaną funkcji?


(Kamiljano) #1

Szukałem po googlach pół dnia i znalazłem wiele odpowiedzi na to właśnie pytanie, ale nawet jedna z nich nie wydawała się być właściwa...

Spytam więc tutaj: jak pobrać wartość zwracaną funkcji z bazy danych Oracla?

Powiedzmy, że mamy następującą funkcję:

create or replace function asdf(a in varchar2) return varchar2 as

begin

return a;

end;

i następujący kod w C#

OracleConnection con = new OracleConnection();

            con.ConnectionString = "User Id=app;Password=password;Data Source=127.0.0.1";

            con.Open();

            Console.WriteLine("Connected to Oracle " + con.ServerVersion);

            OracleCommand cmd = new OracleCommand("asdf", con);

            cmd.CommandType = System.Data.CommandType.StoredProcedure;

            OracleParameter param = new OracleParameter("a", OracleDbType.Varchar2);

            param.Value = "lol";

            cmd.Parameters.Add(param).Direction = ParameterDirection.Input;


            param = new OracleParameter("RETURN_VALUE", OracleDbType.Varchar2);

            param.DbType = DbType.String;

            cmd.Parameters.Add(param).Direction = ParameterDirection.ReturnValue;

            cmd.ExecuteNonQuery();

            Console.WriteLine("Answer: " + cmd.Parameters["RETURN_VALUE"].Value);

            con.Close();

            con.Dispose();

Problem polega na tym, że moja odpowiedź to pusty string... Co więc robię źle?


(Grzelix) #2

sprawdź coś takiego:

var result = cmd.ExecuteScalar();

            Console.WriteLine("Answer: " + result);

(Kamiljano) #3

też już próbowałem i też nie śmiga :confused:


(Grzelix) #4

So, first tutaj jest artykul który można wziąść za podstawę

http://www.c-sharpcorner.com/UploadFile ... otNET.aspx

i zaużyłem ten szczegół:

create or replace procedure count_emp_by_dept(pin_deptno number, pout_count out number)

tak jest definiowana wartość zwraca przez procedurę - parametr out i potem w kodzie:

objCmd.Parameters.Add("pout_count", OracleType.Number).Direction = ParameterDirection.Output;

poza tym kod C# wygląda ok, natomiast mało informacji mamy o procedurze. Więc jeśli to wyżej nie pomoże dobrze się upewnić czy sama procedura działa poprwawnie, i jakie zwraca wartości.


(Tomek Matz) #5
  1. Korzystasz z ODP.NET? Jeśli nie, to zacznij.

  2. Ta linijka jest kompletnie bez sensu (usuń ją z kodu):

    param.DbType = DbType.String;

  3. Zamień kolejność w jakiej dodajesz parametry do kolekcji Parameters. Najpierw dodawaj parametr odpowiadający wartości zwracanej funkcji, a dopiero potem dodawaj parametr(y) odpowiadające argumentom funkcji. 4. Dla typu OracleDbType.Varchar2 musisz jeszcze określić rozmiar (maksymalną ilość znaków), czyli konstruktor będzie wyglądał, np.

    OracleParameter parameter = new OracleParameter("RETURN_VALUE", OracleDbType.Varchar2, 200);

  4. Staraj się jakoś porządkować kod. Na to co wrzuciłeś nie da się patrzeć. Jestem pewien, że gdybyś uporządkował ten kod, to od razu wychwyciłbyś punkt nr 2.

@grzelix

  1. Procedura, a funkcja to nie to samo.

  2. Z System.Data.OracleClient nie powinno się już korzystać (a przynajmniej nie w nowych projektach).