8

我想对 C# 中的 oracle 数据库进行一些编程模式操作。因此,我在一些基本问题上苦苦挣扎。

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

脚本.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 错误:

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

我认为,也许语句的格式存在一些问题。任何提示表示赞赏。谢谢你。

- -编辑 - -

以一种简单的方式总结我的需求:我寻找一种方法来执行任何 sql/ddl 脚本,该脚本可由 SQL Plus 执行,使用 C# 以编程方式。

4

4 回答 4

11

只需将其包裹在 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();
  }
}
于 2015-03-18T06:34:35.443 回答
3

感谢分号提示

我运行 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;
        }
    }
于 2020-02-28T12:45:06.457 回答
1

正如@Steve 所说,分号导致您的错误。而且你不能将整个文件包装成一个execute immediate命令,因为它一次只能执行一个语句。您将需要解析您的文件并自行执行每个命令,删除用于划分命令的分号。正如您所指出的,您的解析将不得不处理字符串文字,除了包含分号之外,还可能在开始和结束字符串文字的单引号 (') 中包含双引号 ('')。

于 2013-07-18T18:59:51.733 回答
1

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

此外,您应该删除行尾的分号

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);
}
于 2013-07-18T14:07:59.060 回答