【问题标题】:Execute Oracle SQL Scripts with C#使用 C# 执行 Oracle SQL 脚本
【发布时间】:2018-08-14 05:34:42
【问题描述】:

我正在使用 C# 开发一个大型解决方案。此解决方案使用不同的 oracle 数据库并在 TFS 中签入。实际上,我开发了一个小型库,可以将解决方案中的 SQL 脚本部署到使用的数据库。应用程序的部署由 TFS 处理,将来我的工具应该包含在构建过​​程中。对于 Oracle 连接,我使用 Oracle.ManagedDataAccess.Client 执行语句。

如果 SQL 文件中只有几个 DDL 或 DML 语句,则第一个测试成功。但是有一些特殊的事情我必须处理,比如 SET DEFINE OFF。这不是真正的 SQL 语句,如果我使用 ORacle SQL*PLus 运行脚本,则没有问题。一开始我尝试执行整个脚本,但这不起作用,因为我的应用程序将多条语句放在一行中,我找到的唯一解决方案是拆分文件和单次执行。

例子:

   /*************************************************************************************************************************
##NAME   ScriptName.sql
##DESCR  ScriptDescription
*************************************************************************************************************************/

Create table tmp_thm_Test
( tmp_thm_Test_id number(8)
, text varchar2(200));

Create table tmp_thm_Test2
( tmp_thm_Test2_id number(8)
, text varchar2(200));

这是脚本的示例内容。也可以有插入(在字符串中有 & 时需要设置定义关闭),更新语句。还有开始/结束脚本。

如果只有 DDL 和 DML 语句,我可以拆分它们,但 Begin/End 部分不可拆分。一开始我以为我可以像过去一样使用 SQL*Plus (@Scriptname.sql) 部署脚本。阅读整个脚本并执行它。

有什么想法吗?

【问题讨论】:

  • 您的要求并不完全清楚。您能否提供您尝试过的代码(简化为minimal, complete and verifiable example),描述您期望发生的事情以及实际发生的事情? SET DEFINE OFF 是 SQL*Plus 的设置,而不是 Oracle DB 服务器的设置。你不应该在通过 ODP.Net 执行的脚本中使用它
  • 嗨 jeroenh,我已经用其他信息编辑了我的帖子。

标签: c# oracle tfs deployment


【解决方案1】:

自从我在 C# 中与 Oracle 合作后,即使没有具体示例,我也能理解你。

SET DEFINE OFF 在 C# 中从来没有为我工作过,所以我只使用 query = query.Replace("'","''");。您还可以使用如下命令参数来避免异常。

        string query = string.Format(
                                    @"UPDATE CardStatus
                                      SET DateExpired = @dateExpired,
                                          ModifiedBy = @modifiedBy,
                                          ModifiedOn = @modifiedOn
                                      WHERE
                                        IDNo = @idNo");

        List<OracleParameter> parameters = new List<OracleParameter>();

        OracleParameter pIdNo = new OracleParameter("idNo", OracleDbType.Varchar2);

        pIdNo.Value = idNo;

        OracleParameter pDateExpired = new OracleParameter("dateExpired", OracleDbType.Date);

        pDateExpired.Value = dateExpired;

        OracleParameter pModifiedBy = new OracleParameter("modifiedBy", OracleDbType.Varchar2);

        pModifiedBy.Value = "SIS";

        OracleParameter pModifiedOn = new OracleParameter("modifiedOn", OracleDbType.Date);

        pModifiedOn.Value = DateTime.Now;

        parameters.Add(pIdNo);
        parameters.Add(pDateExpired);
        parameters.Add(pModifiedBy);
        parameters.Add(pModifiedOn);

        bool result = _DAL.ExecuteNonQuery(query, parameters.ToArray());

_DAL 只是我用于数据访问的辅助类,它管理将其放置在单个事务中的查询执行,以便我决定是提交还是回滚单个到多个查询的更改。

    public bool ExecuteNonQuery(string query, object[] parameters, [CallerMemberName] string callerMemberName = "")
    {
        bool success = false;

        try
        {
            using (OracleCommand command = new OracleCommand())
            {
                command.Connection = _connection;
                command.Transaction = _transaction;
                command.CommandText = query;
                command.CommandType = CommandType.Text;
                command.Parameters.AddRange(parameters);

                command.ExecuteNonQuery();
            }

            this.AuditSQL(query, string.Empty);
            success = true;
        }
        catch (OracleException ex)
        {
            this.AuditSQL(query, ex.Message, callerMemberName);

            if (ex.Number == 54) // SELECT .. FOR UPDATE NOWAIT failed.
            {
                throw new RowLockException();
            }
        }

        return success;
    }

我不确定您是否有兴趣查看我的_DAL 课程,但我为您提供了一个 sn-p,让您了解您可以做什么。

编辑:既然你提到脚本已经存在,那么它就更容易了,你只需要确保脚本中没有 ' 字符就可以让 oracle 请求一个变量值,并且所有批处理查询都必须有BEGINEND;

例子:

BEGIN

-- INSERT
-- UPDATE
-- INSERT
... etc.

END;

现在,您的问题到底是什么?您可以从文件中读取查询并将所有SET DEFINE OFF(以及您认为不必要的其他语句)替换为string.Empty,并在需要时将所有' 替换为''。最坏的情况是,您将使用正则表达式来识别和删除不需要的语句。

【讨论】:

  • 您好约翰,感谢您的反馈。我有一个类似的解决方案。还处理 qoutes 和执行语句。不幸的是,这不是我的问题的解决方案。我有整个 sql 脚本文件要执行。我在帖子中添加了更多信息。亲切的问候托比
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-13
  • 2014-04-16
  • 2013-05-11
  • 1970-01-01
相关资源
最近更新 更多