2008-11-21 49 views
6

¿Cuál es la forma correcta de dividir las sentencias SQL para enviarlas a un cliente Oracle ADO.NET? Por ejemplo, digamos que usted tiene el siguiente código en un archivo de texto y desea ejecutar estas declaraciones:Cómo dividir sentencias Oracle sql para ADO.NET

CREATE TABLE foo (bar VARCHAR2(100)); 
INSERT INTO foo (bar) VALUES('one'); 
INSERT INTO foo (bar) VALUES('two'); 

Creo que tratar de enviar todos los comandos en un solo hará que Oracle para quejarse de la ";". Lo primero que pensé fue dividirme en ";" personaje, y enviarlos uno a la vez.

Pero, los procedimientos almacenados también pueden contener puntos y comas, así que ¿cómo lo haría para que la rutina dividida mantuviera todo el proceso almacenado junto? ¿Necesita buscar también estados de inicio/final o "/"?

¿Hay alguna diferencia en estos aspectos entre ODP.NET y el proveedor de Oracle de Micrsoft?

Respuesta

5

Sin el DDL, se podría crear un bloque PL/SQL anónimos rodeando las declaraciones con BEGIN y END:

BEGIN 
    INSERT INTO foo (bar) VALUES('one'); 
    INSERT INTO foo (bar) VALUES('two'); 
END; 

Para realizar DDL (como CREATE TABLE) que tendría que usar dinámico PL/SQL :

BEGIN 
    EXECUTE IMMEDIATE 'CREATE TABLE foo (bar VARCHAR2(100))'; 
    EXECUTE IMMEDIATE 'INSERT INTO foo (bar) VALUES(:v)' USING 'one'; 
    EXECUTE IMMEDIATE 'INSERT INTO foo (bar) VALUES(:v)' USING 'two'; 
END; 

los insertos también son dinámicos, ya que la tabla no existe antes de ejecutar el bloque y lo que sería un fracaso para compilar.

NOTA: Este sería un requisito inusual: las aplicaciones normalmente no deberían crear tablas.

+0

Estoy tratando de ejecutar el usuario ingresó el SQL básicamente y he cortado la aplicación correctamente para enviarlo al cliente ADO.NET. –

+1

Hmm - ¡No me gustaría apoyar el SQL ingresado por el usuario! ¿También podría darles acceso a SQL Plus? –

1

Una empresa llamada devart (www.devart.com) publicar una biblioteca llamada dotConnect for Oracle.

Esta biblioteca contiene una clase llamada OracleScript que tiene la capacidad de separar un script SQL que contiene varias instrucciones.

0

Para ampliar la respuesta de Tony, puede usar un bloque anónimo para hacer esto, solo tendrá que asegurarse de que la cadena esté funcionando como espera. Este es un ejemplo ABAJO Y SUCIO, casi dividido en; y creando el bloque.

using System; 
using System.Data; 
using System.Text; 
using System.Reflection; 
using Oracle.DataAccess.Client; 
using Oracle.DataAccess.Types; 

namespace ODPSample 
{ 
    class Class1 
    { 

     private static string formatAnonBlock(string userData) 
     { 
      StringBuilder sb = new StringBuilder(); 
      sb.Append("Begin "); 
      string[] statements = userData.Split(';'); 
      foreach (string s in statements) 
      { 
       if (s.Length > 0) 
       { 
        sb.AppendFormat(" EXECUTE IMMEDIATE '{0}';", s.Replace("'", "''")); 
       } 
      } 
      sb.Append(" END ; "); 
      return sb.ToString(); 
     } 
     static void Main(string[] args) 
     { 
      Console.WriteLine("Demo: Anon Block"); 

      // Connect 
      string connectStr = "User Id=scott;Password=tiger;Data Source=database"; 

      string userInputtedSQL; 
      userInputtedSQL = "Create table ABC(val varchar2(50)); insert into ABC values('123');insert into ABC values('567');"; 

      string anonBlock; 
      anonBlock = formatAnonBlock(userInputtedSQL); 
      Console.WriteLine(anonBlock); 

      OracleConnection connection = new OracleConnection(connectStr); 
      OracleCommand cmd = new OracleCommand(anonBlock, connection); 


      try 
      { 
       connection.Open(); 
       cmd.ExecuteNonQuery(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e.Message); 
      } 

      Console.WriteLine("Done"); 
     } 
    } 
} 
Cuestiones relacionadas