2008-11-21 75 views
6

将SQL语句拆分为发送到Oracle ADO.NET客户端的正确方法是什么?举例来说,假设你有一个文本文件,下面的代码,并希望执行这些语句:如何为Oracle ADO.NET拆分Oracle sql语句

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

我相信尝试发送全部在一个命令那些会导致甲骨文抱怨“;”。我的第一个想法是分裂“;”字符,并一次发送一个。

但是,存储过程也可以包含分号,所以我怎样才能使分割例程保持整个存储过程?是否需要查找开始/结束语句,或“/”?

ODP.NET和Micrsoft Oracle Provider在这些方面有什么不同吗?

回答

5

没有DDL,你可以通过周围用BEGIN和END语句创建一个匿名PL/SQL块:

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

要执行DDL(如CREATE TABLE),你将需要使用动态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; 

INSERTS也是动态的,因为在运行块之前表不存在,所以它将无法编译。

注意:这将是一个不寻常的要求:应用程序通常不应该创建表!

+0

我想基本上执行用户输入的SQL,并让应用程序切片正确发送到ADO.NET客户端。 – 2008-11-21 16:12:42

1

一家名为devart的公司(www.devart.com)发布了一个名为dotConnect for Oracle的库。

该库包含一个名为的OracleScript,它能够分离包含多个语句的SQL脚本。

0

要扩大托尼的答案,你可以使用匿名块来做到这一点,你只需要确保字符串按照你的期望工作。这是一个沮丧和肮脏的例子,非常分裂;并创建该块。

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"); 
     } 
    } 
}