繁体   English   中英

当过程处于不同模式时从 C# 调用 Oracle 过程

[英]Call Oracle procedure from C# when procedure is in different schema

我正在尝试调用一个非常简单的过程,如果我在 Toad 编辑器中,它工作正常:

BEGIN OtherSchema.P_CloseBatch('BatchName'); END;

此架构有权执行存在于其他架构中的 P_CloseBatch。

我使用以下代码在 C# 中连接到相同的模式:

try 
{ 
    using (OracleConnection connection = new OracleConnection(oracleStgConnectionString))
    {
          connection.Open();
          OracleCommand command = new OracleCommand();
          command.Connection = connection;
          command.CommandType = CommandType.StoredProcedure;
          command.CommandText = "BEGIN OtherSchema.P_CloseBatch('BatchName'); END;";
          command.ExecuteNonQuery();
          connection.Close();
     }
}
catch (Exception e)
{
     Log.Info(e.Message);
}

当我到达 command.ExecuteNonQuery 时,它给了我一个很长的错误:

{"ORA-06550:第 1 行,第 83 列:\\nPLS-00103:遇到符号 \\")\\" 当期望以下之一时:\\n\\n ( - + case mod new not null \\n \\n continue avg计数当前存在最大最小之前 sql stddev\\n 总和方差执行所有合并时间时间戳间隔\\n 日期\\n 管道\\n \\n

我所有的搜索都使它看起来像 CommandText 是合适的,但事实并非如此。 我能想到的只是它在不同的模式中。 这是问题所在,还是还有其他我没有看到的地方?

如果不是上面的 CommandText 值,我有以下内容:

command.CommandText = "OtherSchema.P_CloseBatch('BatchName')";

然后我得到的错误是:

  • $exception {“ORA-06550:第 1 行,第 7 列:\\nPLS-00801:内部错误 [22503]\\nORA-06550:第 1 行,第 7 列:\\nPL/SQL:忽略语句”} Oracle.ManagedDataAccess.Client。甲骨文异常

我可以将其拆分,以便将命令文本分开,并将批处理名称添加为参数:

 connection.Open();
 OracleCommand command = new OracleCommand();
 command.Connection = connection;
 command.CommandType = CommandType.StoredProcedure;
 command.CommandText = "OtherSchema.P_CloseBatch(:batchname)";
 String parameterBatchName = "BatchName";
 command.Parameters.Add(new OracleParameter(":batchname", parameterBatchName ));
 command.ExecuteNonQuery();
 connection.Close();

该错误是“+ $exception {"ORA-01008: not all variables bound"} Oracle.ManagedDataAccess.Client.OracleException "

这似乎是一个非常简单的错误。 我使用的语法与有效的查询相同,但它们是更新而不是对过程的调用。

当您指定CommandType.StoredProcedureCommandText应该是过程的名称,而不是 PL/SQL 脚本。 参数在Parameters集合中传递。

using (OracleConnection connection = new OracleConnection(oracleStgConnectionString))
using (OracleCommand command = connection.CreateCommand())
{
    connection.Open();

    command.BindByName = true;
    command.CommandType = CommandType.StoredProcedure;
    command.CommandText = "OtherSchema.P_CloseBatch";

    command.Parameters.Add(new OracleParameter()
    {
        ParameterName = "batchname",
        OracleDbType = OracleDbType.NVarchar2
        Value = parameterBatchName
    });

    command.ExecuteNonQuery();

    // Call to connection.Close removed as the "using" block already does that.
}

我还进行了一些其他更改:

  • 使用connection.CreateCommand创建command因为它在返回对象之前分配连接。

  • commandusing块,因为它也是一次性的。

  • 设置BindByName以便我指定的参数名称实际上意味着什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM