简体   繁体   English

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

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

I'm trying to call a pretty simple procedure, and if I'm in the Toad editor, it works fine:我正在尝试调用一个非常简单的过程,如果我在 Toad 编辑器中,它工作正常:

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

This schema has permissions to execute P_CloseBatch that exists in OtherSchema.此架构有权执行存在于其他架构中的 P_CloseBatch。

I'm connecting in C# to the same schema, using this code:我使用以下代码在 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);
}

And when I get to the command.ExecuteNonQuery, it gives me a long error:当我到达 command.ExecuteNonQuery 时,它给了我一个很长的错误:

{"ORA-06550: line 1, column 83:\\nPLS-00103: Encountered the symbol \\")\\" when expecting one of the following:\\n\\n ( - + case mod new not null \\n \\n continue avg count current exists max min prior sql stddev\\n sum variance execute forall merge time timestamp interval\\n date \\n pipe\\n \\n {"ORA-06550:第 1 行,第 83 列:\\nPLS-00103:遇到符号 \\")\\" 当期望以下之一时:\\n\\n ( - + case mod new not null \\n \\n continue avg计数当前存在最大最小之前 sql stddev\\n 总和方差执行所有合并时间时间戳间隔\\n 日期\\n 管道\\n \\n

All my searching makes it look like that CommandText is appropriate, but it's not.我所有的搜索都使它看起来像 CommandText 是合适的,但事实并非如此。 All I can think of is that it's in a different schema.我能想到的只是它在不同的模式中。 Is that the problem, or is there something else I don't see?这是问题所在,还是还有其他我没有看到的地方?

If instead of the CommandText value above, I have the following instead:如果不是上面的 CommandText 值,我有以下内容:

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

Then the error I get is:然后我得到的错误是:

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

I can split it up so the command text is separate, and the batch name is added as a parameter:我可以将其拆分,以便将命令文本分开,并将批处理名称添加为参数:

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

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

That seems like a very simple error.这似乎是一个非常简单的错误。 I'm using the same syntax as queries that do work, but they are updates instead of calls to a procedure.我使用的语法与有效的查询相同,但它们是更新而不是对过程的调用。

When you specify CommandType.StoredProcedure , the CommandText should be the name of the procedure, not a PL/SQL script.当您指定CommandType.StoredProcedureCommandText应该是过程的名称,而不是 PL/SQL 脚本。 The parameter is passed in the Parameters collection.参数在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.
}

I've thrown in a few other changes:我还进行了一些其他更改:

  • Created command using connection.CreateCommand because it assigns the connection before returning the object.使用connection.CreateCommand创建command因为它在返回对象之前分配连接。

  • A using block on command because it's also disposable.commandusing块,因为它也是一次性的。

  • Setting BindByName so the parameter name I specify actually means something.设置BindByName以便我指定的参数名称实际上意味着什么。

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

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