1

I am trying to execute a PL-SQL block in c# using System.Data.OrcaleClient. The PL-SQL block when executed in oracle, prints the result using dbms.ouput.

I want to get that "dbms.ouput" result in my C# code.

Please help.

MatthewMartin
  • 32,326
  • 33
  • 105
  • 164
Dinu
  • 13
  • 2
  • 6
  • Why don't you turn you block into a [function](http://www.techonthenet.com/oracle/functions.php) and _return_ the result? – Ben Mar 03 '12 at 10:57
  • Hi Ben, we are integrating with a third party and they have provided us with the PL-SQL block, to get the required result – Dinu Mar 03 '12 at 10:59

2 Answers2

4

Try to use get_line function of dbms_output package. You can create a procedure to return the output. Something like this (just a example):

procedure call_with_output(p_output out varchar2) is
  vret integer := 0;
  vtxt varchar2(4000);
begin
  dbms_output.enable;
  -- here call code that generate lines
  -- use the loop to retrieve info
  while vret = 0 loop
    dbms_output.get_line(vtxt, vret);
    if vret = 0 then
      if p_output  is null then
        p_output := vtxt;
      else
       p_output := p_output || chr(10) || vtxt;
      end if;
    end if;
  end loop;
  dbms_output.disable;
end;
  • I like your solution. It combines the simplicity of using `get_line` (instead of `get_lines`) with a single call to the server. The answer I was working on involved calling `get_lines` via ODP.NET, which is a ridiculous faff. +1 – Luke Woodward Mar 03 '12 at 13:00
  • 1
    +1 Note, however, that this will only work if the total amount of output is 32k or less. That's probably the case but you can get a decent amount of debug output get written to `dbms_output` if you're generating it in a loop. – Justin Cave Mar 03 '12 at 16:36
  • To get 32K, the declaration of vtxt must be changed to `vtxt varcahr2(32767)` – Shannon Severance Mar 05 '12 at 01:29
  • @Sérgio Michels - Thats a nice solution but the data returned by the pl-sql block is huge.So since there is a size limit in using get_line,I think it wouldnt work :( – Dinu Mar 05 '12 at 07:06
  • @Dinu Try modify the example to insert in a temporary table, instead of return as out of the procedure. –  Mar 05 '12 at 13:26
1

I am using the next method:

    private string GetDbmsOutputLine()
    {
        OracleCommand command = new OracleCommand
        {
            Connection = <connection>,
            CommandText = "begin dbms_output.get_line(:line, :status); end;",
            CommandType = CommandType.Text
        };

        OracleParameter lineParameter = new OracleParameter("line",  
            OracleType.VarChar);
        lineParameter.Size = 32000;
        lineParameter.Direction = ParameterDirection.Output;
        command.Parameters.Add(lineParameter);

        OracleParameter statusParameter = new OracleParameter("status",  
            OracleType.Int32);
        statusParameter.Direction = ParameterDirection.Output;
        command.Parameters.Add(statusParameter);

        command.ExecuteNonQuery();

        if (command.Parameters["line"].Value is DBNull)
            return null;

        string line = command.Parameters["line"].Value as string;

        return line;
    }

Call it several times to get multistring value because there are problems with calling dbms_output.get_lines with System.Data.OracleClient.

SKINDER
  • 950
  • 3
  • 17
  • 39