Oracle

Mono vem com um cliente Oracle o assembly System.Data.OracleClient que acompanha a biblioteca Microsoft System.Data.OracleClient. Esta biblioteca foi descontinuada pela Microsoft e não é mais mantida.

A Oracle produz um cliente para Windows, mas este não é suportado pelo Mono.

Alguns providers comerciais para Mono estão disponíveis:

Índice

Informações

  • ADO.NET Data Provider para banco de dados Oracle

  • Está no namespace System.Data.OracleClient e assembly System.Data.OracleClient.dll

  • Funciona no Windows, Linux x86, e Solaris x86. Você pode nos ajudar a fazê-lo funcionar em outros sistemas, tais como, Solaris SPARC e Mac OS X?

  • Funciona com as versões do Oracle 8i, 9i, 10g, and 11g

  • Utilize OCI (Oracle call-level interface) que é uma biblioteca C para acessar bancos de dados Oracle

  • System.Data.OracleClient foi descontinuado pela Microsoft na versão .Net 4.0

  • Outras alternativas que funcionam no Mono, porém não estão inclusos como o Mono - dotConnect for Oracle

Status atual para System.Data.OracleClient

  • Existem duas maneiras para conectar-se com o Oracle: utilizando o Usuário e Senha ou utilizando uma autenticação externa, usando “Integrated Security=true” em sua string de conexão

  • OracleCommandBuilder foi implementado e permite você fazer Inserts/Updates/Deletes com DataSet e OracleDataAdapter. No entando o OracleDataReader necessita de maiores implementações para permitir que seja utilizado KeyInfo para recuperar alguns metadaos da consulta executada. O analisador de consultas Oracle SQL é muito simples e não será capaz de lidar com consultas complexas. Neste sentido, você necessitará de um analisador Oracle SQL real, utilizando o compilador jay. Jay é usado por mcs para analisar arquivos c# e para o System.Data analisar expressões em um DataColumn.

  • REF CURSOR podem ser retornados por stored procedures com um OracleDataReader através de um parâmetro de output definido como OracleType.Cursor

  • Pool de conexões estão funcionando

  • OracleConnection pode conectar-se em Oracle 8i, 9i e 10g através de OCI (Oracle Call Level Interface)

  • Parâmetros de input e output (char, varchar2, number, date, raw, long varchar, blob, clob and timestamp) pode agora ser utilizado na instruções SQL, blocos PL/SQL e stored procedures.

  • Parâmetros Input/Output e Return não foram testados.

  • OracleException and tratamento de erros existentes.

  • Tratamento de mensagens precisam ser adicionados para mensagens não críticas recebidas pelo Oracle (EM ANDAMENTO)

  • Manipuladores de vários tipos de dados precisam ser adicionados (EM ANDAMENTO)

  • DataSet pode ser preenchido por DataAdapter.

  • Pode não funcionar em plataformas não X86 como Mac OS ou Solaris SPARC. Não funciona devido à problemas com byte-ordering e diferenças entre alguns processadores. Nós estas aceitando patches de correção para que funcione nestas plataformas.

Plano de Ação

  • Suporte à limpeza dos parâmetros (Parâmetros de Input e Output FUNCIONANDO). Parâmetros de Input/Output e Return precisam FAZER)

  • Suporte para Oracle 8i no Linux e Windows (FUNCIONANDO).

  • Suporte para Oracle 9i no Linux e Windows (FUNCIONANDO. Ainda precisa adicionar recursos para 9i).

  • Suporte para Oracle 10g no Linux e Windows (FUNCIONANDO. Ainda precisa adicionar recursos para 10g).

  • Suporte para Oracle 10g no Mac OS X. Exige resolução de problemas de byte-ordering e alinhamento. (PARA FAZER).

  • Suporte para Oracle 10g no Solaris x86. (FUNCIONANDO no Solaris 10 x86 e Solaris Express x86).

  • Suporte para Oracle 10g no Solaris SPARC. Exige resolução de problemas de byte-ordering e alinhamento. (PARA FAZER).

  • Suporte para Oracle 10g Express Edition no Windows e Linux (FUNCIONANDO).

  • Suporte para Oracle 11g no Linux e Windows (FUNCIONANDO).

  • Suporte a grandes objetos como LONG VARCHAR, BLOB, CLOB (FUNCIONANDO).

  • Suporte todos os tipos de dados (AINDA DE EXECUÇÃO). Ainda precisa implementar INTERVAL. Muitos dos tipos Oracle .net, como OracleDateTime utilizam internamente os tipos definidos em .NET como DateTime. Isto é insuficiente para suportar tipos de dados do Oracle como TIMESTAMP.

  • Auditoria de Segurança (PARA FAZER)

  • NLS / Suporte a Unicode / conjunto de caracteres Multi-byte (PRECISAM MELHORAR)

Testando

Pré-requisitos

  • Tenha o mono e gmcs funcionando.

  • Ter acesso ao Oracle 8i, 9i, 10g, 10g Express, ou 11g ou realizar o download em Oracle Downloads. Se você está se conectando remotamente a um banco de dados Oracle, é necessário o software cliente Oracle. As inscrições para o Oracle Technology Network é grátis. Se estiver instalando o Linux, sugiro que você pesquise bastante para ver como outros instalaram o Oracle no Linux. Werner Puschitz’s Oracle on Linux page contém bons guias passo-a-passo pra a instalação do Oracle no Linux.

  • Oracle Database 10g Express Edition é grátis para download e redistribuição. Ele funciona no Windows e Linux, além disto ele é bem mais fácil de instalar se comparado com as versões Standard e Enterprise.

  • Se você nao tem nenhum Oracle instalado no computador em que você está executando o Mono, mas você precisa acessar o banco de dados Oracle remotamente, sugiro que utilize Oracle Instant Client. O Oracle Instant Client é bem mais fácil de instalar do que um cliente Oracle. Você também pode redistribuir o Oracle Instant Client gratuitamente.

  • A instalação do Oracle 10g Express Edition (XE) no Debian/Ubuntu Linux é feita via apt-get.

Basicamente, você adiciona em seu /etc/apt/sources.list

deb http://oss.oracle.com/debian unstable main non-free

em então execute o seguinte:

sudo apt-get update
sudo apt-get install oracle-xe-universal
sudo /etc/init.d/oracle-xe configure
  • No mcs você pode encontrar códigos fontes e teste em mcs/class/System.Data.OracleClient/Test

  • O Data Source está no Oracle TNS Name

Formato da string de conexão

  • Segue o formato da string de conexão:
"Data Source=tnsname;User ID=userid;Password=password"

Formato da string de conexão utilizando descrição de rede TNS sem utilizar o arquivo tnsnames.ora

  • Segue o formato da string de conexão:
"User ID=SCOTT;" +
"Password=TIGER;" +
"Data Source=(" +
"DESCRIPTION=(" +
"ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.101)(PORT=1521))" +
"(CONNECT_DATA=(SERVER=DEDICATED)" +
"(SERVICE_NAME=TESTDB)))"

Formato da string de conexão para autenticação externa

  • Segue o formato da string de conexão:
"Data Source=tnsname;Integrated Security=true"
  • Parâmetros da string de conexão:
Definição do parâmetro Descrição Exemplo
Server or Data Source TNS Name ou Network Address da instância do Oracle para conectar Server=TESTDB
User ID nome do usuário de banco de dados Oracle User ID=scott
Password senha para o usuário de banco de dados Oracle Password=mypass12
Integrated Security Para conectar utilizando autenticação externa ou não. Valores válidos para Integrated Security são: YES ou TRUE para utilizar autenticação externa. NO ou FALSE para não utilizar autenticação externa. Padrão é false. Integrated Security=true
Min Pool Size Determina o número mínimo de conexões para o pool de conexões. Padrão é 0. Min Pool Size=0
Max Pool Size Determina o número máximo de conexões para o pool de conexões. Padrão é 100. Max Pool Size=100
Pooling Determina se deve ou não utilizar o pool de conexões. Valores válidos são TRUE ou YES para utilizar o pool de conexões ou FALSE ou NOT para não utilizar o pool de conexões. Padrão é TRUE. Pooling=true
  • Se você usar a autenticação externa, certifique-se de ter um usuário criado externamente. Além disso, verifique se você sabe o que está fazendo, se você usar a autenticação externa - há implicações de segurança. Leia Oracle® Database Advanced Security Administrator’s Guide para mais informações sobre a autenticação externa.

  • Como criar um usuário do Windows chamado SomeUser no Windows NT/2000 Domínio MyNTDomain para autenticação externa no Oracle: Se você não estiver em um domínio do Windows, então o Nome da sua Máquina é o domínio. Observe como o usuário do domínio é entre aspas duplas e é maiúsculas.

CREATE USER "MYNTDOMAIN\\SOMEUSER" IDENTIFIED EXTERNALLY;
  • Como criar um usuário no Linux chamado someuser no Oracle com permissão de autenticação externa:
CREATE USER someuser IDENTIFIED EXTERNALLY;

Exemplos

C# Exemplo 1a - Conexão básica e recuperação de dados

 using System;
 using System.Data;
 using System.Data.OracleClient;
 
 public class Test
 {
    public static void Main (string[] args)
    {
       string connectionString =
          "Data Source=testdb;" +
          "User ID=scott;" +
          "Password=tiger;";
       OracleConnection dbcon = null;
       dbcon = new OracleConnection (connectionString);
       dbcon.Open ();
       OracleCommand dbcmd = dbcon.CreateCommand ();
       string sql = "SELECT ename, job FROM scott.emp";
       dbcmd.CommandText = sql;
       OracleDataReader reader = dbcmd.ExecuteReader ();
       while (reader.Read ()) {
          string employeeName = (string) reader["ename"];
          string job = (string) reader["job"];
          Console.WriteLine ("Employee Name: {0}  Job: {1}",
                            employeeName, job);
       }
       // clean up
       reader.Close ();
       reader = null;
       dbcmd.CommandText = sql;
       dbcmd.ExecuteNonQuery ();
       dbcmd.Dispose ();
       dbcmd = null;
       dbcon.Close ();
       dbcon = null;
    }
 }

C# Exemplo 1b - Conexão básica e recuperação de dados utilizando Integrated Security

 using System;
 using System.Data;
 using System.Data.OracleClient;
 
 public class Test
 {
    public static void Main (string[] args)
    {
       string connectionString =
          "Data Source=testdb;" +
          "Integrated Security=true";
       OracleConnection dbcon = null;
       dbcon = new OracleConnection (connectionString);
       dbcon.Open ();
       OracleCommand dbcmd = dbcon.CreateCommand ();
       string sql = "SELECT ename, job FROM scott.emp";
       dbcmd.CommandText = sql;
       OracleDataReader reader = dbcmd.ExecuteReader ();
       while (reader.Read ()) {
          string employeeName = (string) reader["ename"];
          string job = (string) reader["job"];
          Console.WriteLine ("Employee Name: {0}  Job: {1}",
                            employeeName, job);
       }
       // clean up
       reader.Close ();
       reader = null;
       dbcmd.CommandText = sql;
       dbcmd.ExecuteNonQuery ();
       dbcmd.Dispose ();
       dbcmd = null;
       dbcon.Close ();
       dbcon = null;
    }
 }

C# Exemplo 2 - Chamando uma Stored Procedure

 using System;
 using System.Data;
 using System.Data.OracleClient;
 
 public class Test
 {
    public static void Main (string[] args)
    {
       string connectionString =
          "Data Source=testdb;" +
          "User ID=scott;" +
          "Password=tiger;";
       OracleConnection dbcon = null;
       dbcon = new OracleConnection (connectionString);
       dbcon.Open ();
 
       Console.WriteLine("  Drop table MONO_TEST_TABLE2...");
       OracleCommand dbcmd = dbcon.CreateCommand ();
 
       try {
              dbcmd.CommandText = "DROP TABLE MONO_TEST_TABLE2";
              dbcmd.ExecuteNonQuery ();
       }
       catch(OracleException oe1) {
              // ignore if table already exists
       }
 
       Console.WriteLine("  Drop procedure SP_TEST2...");
       try {
              dbcmd.CommandText = "DROP PROCEDURE SP_TEST2";
              dbcmd.ExecuteNonQuery ();
       }
       catch(OracleException oe1) {
              // ignore if table already exists
       }
 
       Console.WriteLine("  Create table MONO_TEST_TABLE2...");
 
       dbcmd.CommandText = "CREATE TABLE MONO_TEST_TABLE2 (" +
              " COL1 VARCHAR2(8), "+
              " COL2 VARCHAR2(32))";
       dbcmd.ExecuteNonQuery ();
 
       Console.WriteLine("  Create stored procedure SP_TEST2...");
       dbcmd.CommandText =
              "CREATE PROCEDURE SP_TEST2(parm1 VARCHAR2,parm2 VARCHAR2) " +
              " IS " +
              " BEGIN " +
              "      INSERT INTO MONO_TEST_TABLE2 (COL1,COL2) VALUES (parm1,parm2);" +
              "      COMMIT;" +
              " END;";
 
              cmd2.ExecuteNonQuery ();
 
       Console.WriteLine("  COMMIT...");
       dbcmd.CommandText = "COMMIT";
       dbcmd.ExecuteNonQuery ();
 
       Console.WriteLine("  Call stored procedure SP_TEST2 with two parameters...");
       OracleCommand dbcmd = con.CreateCommand ();
       dbcmd.CommandType = CommandType.StoredProcedure;
       dbcmd.CommandText = "sp_test2";
 
       OracleParameter myParameter1 = new OracleParameter("parm1", OracleType.VarChar);
       myParameter1.Value = "myval";
       myParameter1.Size = 8;
       myParameter1.Direction = ParameterDirection.Input;
 
       OracleParameter myParameter2 = new OracleParameter("parm2", OracleType.VarChar);
       myParameter2.Value = "another";
       myParameter2.Size = 32;
       myParameter2.Direction = ParameterDirection.Input;
 
       dbcmd.Parameters.Add (myParameter1);
       dbcmd.Parameters.Add (myParameter2);
 
       dbcmd.ExecuteNonQuery ();
 
       dbcmd.CommandText = sql;
       dbcmd.ExecuteNonQuery ();
       dbcmd.Dispose ();
       dbcmd = null;
       dbcon.Close ();
       dbcon = null;
    }
 }

C# Exemplo 3 - Executando um bloco PL/SQL

Por que eu faria isso? Vamos dizer que eu precise executar uma stored procedure, porém ainda não é suportado o tipo boolean no OCI. Então eu posso fazer isto através de um bloco PL/SQL.

 using System;
 using System.Data;
 using System.Data.OracleClient;
 
 public class Test
 {
    public static void Main (string[] args)
    {
       string connectionString =
          "Data Source=testdb;" +
          "User ID=scott;" +
          "Password=tiger;";
       OracleConnection con = null;
       con = new OracleConnection (connectionString);
       con.Open ();
        OracleCommand cmd = con.CreateCommand();
        Console.WriteLine("  Drop procedure SP_TESTPLSQLBLOCK1...");
        try
        {
            cmd.CommandText = "DROP PROCEDURE SP_TESTPLSQLBLOCK1";
            cmd.ExecuteNonQuery ();
        }
        catch(OracleException oe1)
        {
            // ignore if table already exists
        }
 
        Console.WriteLine("  Create stored procedure SP_TESTPLSQLBLOCK1...");
        // stored procedure add two number depending on a boolean
 
        cmd.CommandText =
            "CREATE OR REPLACE PROCEDURE SP_TESTPLSQLBLOCK1(PARM1 IN NUMBER,PARM2 IN BOOLEAN,PARM3 OUT NUMBER)\n" +
            "IS\n" +
            "BEGIN\n" +
            "   IF PARM2 = TRUE THEN\n" +
            "       PARM3 := PARM1 + 7;\n" +
            "    ELSE\n" +
            "       PARM3 := PARM1 + 13;\n" +
            "   END IF;\n" +
            "END;";
 
        cmd.ExecuteNonQuery ();
 
        Console.WriteLine("  COMMIT...");
        cmd.CommandText = "COMMIT";
        cmd.ExecuteNonQuery ();
 
        Console.WriteLine("  Call stored procedure SP_TESTPLSQLBLOCK1 with 3 parameters...");
        cmd.CommandType = CommandType.Text;
        cmd.CommandText =
            "DECLARE " +
            "   addnum BOOLEAN := sys.diutil.int_to_bool(:P2); " +
            "BEGIN " +
            "    SP_TESTPLSQLBLOCK1(:P1,addnum,:P3); " +
            "END;";
        OracleParameter myParameter1 = new OracleParameter("P1", OracleType.Number);
        myParameter1.Value = 5;
        myParameter1.Direction = ParameterDirection.Input;
 
        OracleParameter myParameter2 = new OracleParameter("P2", OracleType.Number);
        myParameter2.Value = 1;
        myParameter2.Direction = ParameterDirection.Input;
 
        OracleParameter myParameter3 = new OracleParameter("P3", OracleType.Number);
        myParameter3.Direction = ParameterDirection.Output;
 
        cmd.Parameters.Add (myParameter1);
        cmd.Parameters.Add (myParameter2);
        cmd.Parameters.Add (myParameter3);
 
        cmd.ExecuteNonQuery ();
        decimal d = (decimal) myParameter3.Value;
        Console.WriteLine ("    Out Value should be: 12");
        Console.WriteLine ("    Out Value: {0}", d);
        cmd.Dispose();
        cmd = null;
        con.Close();
        con = null;
    }
 }

C# Exemplo 4 - ASP.NET DataGrid Data Binding para uma tabela em um banco de dados Oracle

Primeiro, você precisará ter certeza que existe a tabela chamada CUSTOMERS com alguns dados.

 CREATE TABLE CUSTOMERS (
    person varchar2(256) NOT NULL,
    email varchar2(256) NOT NULL
 );
 
 INSERT INTO CUSTOMERS
 (PERSON, EMAIL)
 VALUES('Bob Jones','bjones@nowhere.edu');
 
 INSERT INTO CUSTOMERS
 (PERSON, EMAIL)
 VALUES('John Smith','jswmith@somewhere.com');
 
 COMMIT;
<%@ Page Language="C#" %>
<%@ import namespace="System.Data" %>
<%@ import namespace="System.Data.Common" %>
<%@ import namespace="System.Data.SqlTypes" %>
<%@ import namespace="System.Data.OracleClient" %>
<%@ import namespace="System.Reflection" %>
<%@ assembly Name="System.Data.OracleClient" %>
 
<html>
<head>
<title>ASP.NET DataGrid Data Binding to an Oracle database table</title>
 
<!-- Source code modified from samples in xsp was originally made by Gonzalo Paniagua Javier -->
 
<script runat="server">
 
    static Type cncType = null;
 
    void GetConnectionData (out string providerAssembly,
                               out string cncTypeName, out string cncString)
    {
        providerAssembly = null;
        cncTypeName = null;
        cncString = null;
        NameValueCollection config =
                       ConfigurationSettings.AppSettings as NameValueCollection;
        if (config != null) {
            foreach (string s in config.Keys) {
                if (0 == String.Compare ("DBProviderAssembly", s, true)) {
                    providerAssembly = config [s];
                } else if (0 == String.Compare ("DBConnectionType", s, true)) {
                    cncTypeName = config [s];
                } else if (0 == String.Compare ("DBConnectionString", s, true)) {
                    cncString = config [s];
                }
            }
        }
 
        if (providerAssembly == null || providerAssembly == "")
            providerAssembly = "System.Data.OracleClient";
 
        if (cncTypeName == null || cncTypeName == "")
            cncTypeName = "System.Data.OracleClient.OracleConnection";
 
        if (cncString == null || cncString == "")
            cncString = "Data Source=TESTDB;User ID=scott;Password=tiger";
    }
 
    IDbConnection cnc;
    void Page_Load (object o, EventArgs e)
    {
        string connectionTypeName;
        string providerAssemblyName;
        string cncString;
 
        GetConnectionData (out providerAssemblyName,
                       out connectionTypeName, out cncString);
        if (cncType == null) {
            Assembly dbAssembly = Assembly.LoadWithPartialName (
                                                      providerAssemblyName);
            cncType = dbAssembly.GetType (connectionTypeName, true);
            if (!typeof (IDbConnection).IsAssignableFrom (cncType))
                throw new ApplicationException (
                                        "The type '" + cncType +
                    "' does not implement IDbConnection.\n" +
                    "Check 'DbConnectionType' in web.config");
        }
 
        cnc = (IDbConnection) Activator.CreateInstance (cncType);
        cnc.ConnectionString = cncString;
 
        cnc.Open ();
 
        OracleCommand cmd = (OracleCommand) cnc.CreateCommand();
        cmd.CommandText = "select * from CUSTOMERS";
        DbDataAdapter adapter = new OracleDataAdapter(cmd);
        DataTable table = new DataTable("CUSTOMERS");
        adapter.Fill(table);
        grid.DataSource = table;
        grid.DataBind ();
 
        cmd.Dispose();
        cmd = null;
        cnc.Close ();
    }
 
    void Page_PreRender (object sender, EventArgs e)
    {
        if (cnc == null)
            return;
    }
 
 </script>
 </head>
 <body>
 <h3>DataGrid sample</h3>
 <form runat="server">
    <asp:datagrid id="grid" border="1"
        EnableViewState="false" runat="server">
    </asp:datagrid>
 </form>
 </body>
 </html>

C# Exemplo 5 - Retornando um REF CURSOR de uma stored procedures no Oracle utilizando um OracleDataReader para um parâmetro de saída

 using System;
 using System.Data;
 using System.Data.OracleClient;
 
 public class Test
 {
    public static void Main (string[] args)
    {
        string connectionString =
          "Data Source=testdb;" +
          "User ID=scott;" +
          "Password=tiger;";
        OracleConnection connection = null;
        connection = new OracleConnection (connectionString);
        connection.Open ();
 
    Console.WriteLine("Setup test package and data...");
    OracleCommand cmddrop = connection.CreateCommand();
 
    cmddrop.CommandText = "DROP TABLE TESTTABLE";
    try {
        cmddrop.ExecuteNonQuery();
    }
    catch(OracleException e) {
        Console.WriteLine("Ignore this error: " + e.Message);
    }
    cmddrop.Dispose();
    cmddrop = null;
 
    OracleCommand cmd = connection.CreateCommand();
 
    // create table TESTTABLE
    cmd.CommandText =
        "create table TESTTABLE (\n" +
        " col1 numeric(18,0),\n" +
        " col2 varchar(32),\n" +
        " col3 date)";
    cmd.ExecuteNonQuery();
 
    // insert some rows into TESTTABLE
    cmd.CommandText =
        "insert into TESTTABLE\n" +
        "(col1, col2, col3)\n" +
        "values(45, 'Mono', sysdate)";
    cmd.ExecuteNonQuery();
 
    cmd.CommandText =
        "insert into TESTTABLE\n" +
        "(col1, col2, col3)\n" +
        "values(136, 'Fun', sysdate)";
    cmd.ExecuteNonQuery();
 
    cmd.CommandText =
        "insert into TESTTABLE\n" +
        "(col1, col2, col3)\n" +
        "values(526, 'System.Data.OracleClient', sysdate)";
    cmd.ExecuteNonQuery();
 
    cmd.CommandText = "commit";
    cmd.ExecuteNonQuery();
 
    // create Oracle package TestTablePkg
    cmd.CommandText =
        "CREATE OR REPLACE PACKAGE TestTablePkg\n" +
        "AS\n" +
        "    TYPE T_CURSOR IS REF CURSOR;\n" +
        "\n" +
        "    PROCEDURE GetData(tableCursor OUT T_CURSOR);\n" +
        "END TestTablePkg;";
    cmd.ExecuteNonQuery();
 
    // create Oracle package body for package TestTablePkg
    cmd.CommandText =
        "CREATE OR REPLACE PACKAGE BODY TestTablePkg AS\n" +
        "  PROCEDURE GetData(tableCursor OUT T_CURSOR)\n" +
                "  IS\n" +
        "  BEGIN\n" +
        "    OPEN tableCursor FOR\n" +
        "    SELECT *\n" +
        "    FROM TestTable;\n" +
        "  END GetData;\n" +
        "END TestTablePkg;";
    cmd.ExecuteNonQuery();
 
    cmd.Dispose();
    cmd = null;
 
    Console.WriteLine("Set up command and parameters to call stored proc...");
    OracleCommand command = new OracleCommand("TestTablePkg.GetData", connection);
    command.CommandType = CommandType.StoredProcedure;
    OracleParameter parameter = new OracleParameter("tableCursor", OracleType.Cursor);
    parameter.Direction = ParameterDirection.Output;
    command.Parameters.Add(parameter);
 
    Console.WriteLine("Execute...");
    command.ExecuteNonQuery();
 
    Console.WriteLine("Get OracleDataReader for cursor output parameter...");
    OracleDataReader reader = (OracleDataReader) parameter.Value;
 
    Console.WriteLine("Read data...");
    int r = 0;
    while (reader.Read()) {
        Console.WriteLine("Row {0}", r);
        for (int f = 0; f < reader.FieldCount; f ++) {
            object val = reader.GetValue(f);
            Console.WriteLine("    Field {0} Value: {1}", f, val);
        }
        r ++;
    }
    Console.WriteLine("Rows retrieved: {0}", r);
 
    Console.WriteLine("Clean up...");
    reader.Close();
    reader = null;
    command.Dispose();
    command = null;
 
        connection.Close();
        connection = null;
    }
 }

Construindo C# Examples

Salve o exemplo em um arquivo, como, TestExample.cs

  • Compilando com compilador Mono C#:
mcs TestExample.cs /r:System.Data.dll /r:System.Data.OracleClient.dll
  • Executando o exemplo:
mono TestExample.exe