.NET / Oracle:如何以编程方式执行包含SQL语句的脚本

gev0vcfq  于 2023-10-16  发布在  Oracle
关注(0)|答案(4)|浏览(125)

我想用C#对Oracle数据库进行一些编程模式操作。因此,我在一些基本问题上挣扎。
ddl sql语句位于脚本文件中。我不想使用sqlplus.exe,但我想使用ODP.NET程序集(System.Oracle.DataAccess)中的OracleCommand。下面是我的脚本文件的一个例子:
script.sql:

DROP TABLE ABCDEF; 

DROP TABLE GHIJKL;

我想指出:

  • 该脚本包含数据定义语言(Data Definition Language)
  • 脚本包含空行
  • 脚本包含多个语句

下面的代码应该执行我的脚本:

var content = File.ReadAllText("script.sql");

using (var oracleConnection = new OracleConnection(_connectionString))
{
     oracleConnection.Open();

     using (var command = new OracleCommand(content) { Connection = oracleConnection })
     {
          command.CommandType = CommandType.Text;
          command.ExecuteNonQuery();
     }
}

执行这段代码时,我确实得到了一个oracle错误:

Oracle.DataAccess.Client.OracleException:ORA-00911:无效字符

我想,可能是陈述的格式有问题。任何提示都很感激。谢谢

-编辑-

用一个简单的方式来概括我的需求:我寻找一种方法来执行任何sql/ddl脚本,这是可执行的SQL Plus,编程与C#。

vuv7lop3

vuv7lop31#

简单地把它包在开始和END里面,它就能顺利工作了

var content =string.Format("BEGIN {0} END;", File.ReadAllText("script.sql"));
using (var oracleConnection = new OracleConnection(_connectionString))            
{
  oracleConnection.Open();
  using (var command = new OracleCommand(content) { Connection = oracleConnection })
  {
       command.CommandType = CommandType.Text;
       command.ExecuteNonQuery();
  }
}
mqkwyuun

mqkwyuun2#

谢谢你给我的小费!
我的最终代码运行甲骨文脚本!
1)它接受:- 空行/注解(--)行-以结尾的多行DDI/ DML命令;
2)在错误的情况下,它抛出一个异常与行号和sql命令!

public async Task ExecuteScript(string _connectionString, string script)
    {
        using (StringReader sr = new StringReader(script))
        {
            var connection = new OracleConnection(_connectionString);
            connection.Open();

            string sqlCommand = "";
            string sqlLine; byte lineNum = 0;

            while ((sqlLine = sr.ReadLine()) != null)
            {
                sqlLine = sqlLine.Trim(); ++lineNum;

                if (sqlLine.Length > 0 && !sqlLine.StartsWith("--"))
                {
                     sqlCommand += (sqlCommand.Length > 0 ? Environment.NewLine : "") + sqlLine;  // Accept multiline SQL

                    if (sqlCommand.EndsWith(";"))
                    {
                        sqlCommand = sqlCommand.Substring(0, sqlCommand.Length - 1);

                        var command = new OracleCommand(sqlCommand, connection);

                        try
                        {
                            await command.ExecuteNonQueryAsync(); 
                        }
                        catch (OracleException ex)
                        {
                            connection.Close();
                            var e2 = new Exception($"{lineNum} - {sqlCommand} <br/> {ex.Message}");
                            throw e2;
                        }
                    }
                }
            }

            connection.Close();

            return;
        }
    }
w8biq8rn

w8biq8rn3#

正如@史蒂夫所说,是那些混蛋造成了你的错误。您不能将整个文件 Package 到一个execute immediate命令中,因为这一次只能执行一条语句。您将需要解析文件并单独执行每个命令,从而消除删除命令的障碍。解析必须处理字符串文字,如您所述,除了包含双引号外,还可能在字符串文字的开始和结束的单引号(“)中包含双单引号(”)。

anhgbhbe

anhgbhbe4#

我将尝试一次执行一行,看看是否有任何奇怪的字符阻止执行。(我也不确定你是否可以在一个电话中发送所有命令)。
此外,您应该删除行尾的标记

int lineNum = 0;
try
{
    string[] cmdTexts = File.ReadAllLines("script.sql");

    using (var oracleConnection = new OracleConnection(_connectionString))
    {
         oracleConnection.Open();
         OracleCommand command = new OracleCommand();
         command.Connection = oracleConnection;
         foreach(string cmd in cmdTexts)
         {
              lineNum++;
              if(cmd.Trim().Length > 0)
              {
                  if(cmd.EndsWith(";"))
                      cmd = cmd.Substring(0, cmd.Length - 1);

                  command.CommandText = cmd;
                  command.ExecuteNonQuery();
              }
         }
    }
}
catch(Exception ex)
{
    MessageBox.Show("Exception on line: " + lineNum + " message: " + ex.Message);
}

相关问题