.NET/Oracle:如何以编程方式使用DDL语句执行脚本

本文关键字:方式使 DDL 语句 脚本 执行 编程 Oracle NET | 更新日期: 2023-09-27 18:23:51

我想对C#中的oracle数据库进行一些编程模式操作。因此,我很难解决一些基本问题。

ddl-sql语句位于脚本文件中。我不想使用sqlplus.exe,但我想在ODP.NET程序集(System.Oracle.DataAccess)之外使用OracleCommand

script.sql:

DROP TABLE ABCDEF; 
DROP TABLE GHIJKL;

我想指出:

  • 脚本包含DDL语句(数据定义语言)
  • 脚本包含空行
  • 脚本包含多个语句

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

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.DataAccess.Client.OracleException:ORA-00911:无效字符

我认为,也许这些语句的格式有问题。任何提示都将不胜感激。非常感谢。

---编辑---

用一种简单的方式总结我的需求:我搜索一种方法来执行任何sql/ddl脚本,该脚本可由sql Plus通过C#编程执行。

.NET/Oracle:如何以编程方式使用DDL语句执行脚本

只需将其包裹在BEGIN和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();
  }
}

感谢分号提示

我运行oracle脚本的最后一段代码!

1) 它接受:-空行/注释(--)行-以;结尾的多行DDl/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;
        }
    }

正如@Steve所说,分号导致了您的错误。而且,您不能将整个文件包装成一个execute immediate命令,因为它一次只能执行一条语句。您将需要解析文件,并单独执行每个命令,删除使命令脱钩的分号。正如您所指出的,您的解析将必须处理字符串文字,这些文字除了包含分号外,还可能在字符串文字的开头和结尾的单引号(')中包含双单引号('')。

我将尝试一次执行一行,看看是否有任何奇怪的字符阻止执行。(我也不确定你是否可以在一次通话中同时发送所有命令)。

您还应该删除行末尾的分号

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