关于oracle:C# ODB.NET Out 参数总是DBNull | 珊瑚贝

C# ODB.NET Out parameter is always DBNull


我在 Oracle SQL Server 的包中有一个存储过程。
这个过程有输入和输出参数。该过程本身有效,当在 Oracle SQL Developer 中执行时,输出参数读取预期的输出(最后一行的列值)。
此过程必须由 Web API 通过 ODP.NET(Oracle 托管数据访问)调用。

问题:永远不会返回输出参数(ODP 中的 Long 类型和 db 中的 NUMBER(12,0) 类型)。执行命令后输出参数始终为 DBNull。

下面是我的代码的相关部分(其他参数省略):
打包程序:

1
2
3
4
5
PROCEDURE post_event (event_id OUT OPIS_REGISTRATIE_PROJ.PROJECT_ID%TYPE)
IS BEGIN
Some stuff that‘s happening (that works)
SELECT MAX(PROJECT_ID) INTO event_id FROM OPIS_REGISTRATIE_PROJ WHERE PERSOON_ID = worksheet_id;
END;

使用的参数:

1
parameters.Add(new OracleParameter(“event_id”, OracleDbType.Long, ParameterDirection.Output));

C#中的调用代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
if (con.State == ConnectionState.Open)
{
    // Create command and set parameters
    using (var cmd = new OracleCommand(cmdText, con))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        foreach (var p in parameters)
        {
            cmd.Parameters.Add(p);
        }

        // Execute the stored procedure
        try
        {
            cmd.ExecuteNonQuery();
        }
        catch (OracleException ex)
        {
            Console.WriteLine(ex.Message);
        }

long paramEventId = 0;
if (cmd.Parameters[“event_id”].Value != DBNull.Value)
{
    paramEventId = (long)(OracleDecimal)cmd.Parameters[“event_id”].Value;
}

如您所见,我知道如何检查 DBNull 值,但这不是问题。它不应该获得 DBNull 值。

到目前为止我尝试过的一些事情:

  • 将 Parameter DBType 更改为 Int64 和其他(与其他人一起,我正确地得到了关于参数类型的错误)
  • 将 event_id 硬编码为一个值 (event_id := 1234567;)
  • 在数据库中直接在过程之外执行 SELECT MAX(… 查询。

尽管 SQL Developer 按预期工作,但我尝试的一切。
将输出参数传输到调用 C# API 是有问题的。
我用谷歌搜索了很多,也搜索了 Stackoverflow,所以我希望有人能帮助我找到一个可行的答案。

  • 您可以在执行查询之前添加 c# out 参数(属性值)的状态详细信息吗?
  • 在读取参数值之前关闭连接。
  • @Igor 我不确定你的意思/我该怎么做。参数值为空,因为它是一个输出参数。执行后变为 DBNull。史蒂夫,谢谢你的提示,我没想到。不幸的是,这并不能解决我的问题。此外,我还有其他程序在不关闭连接的情况下工作几乎相同(这是必要的,因为这些程序使用 ref 游标)。
  • 抱歉-我错过了您正在调用存储过程的事实-我的回答不适用。
  • @PaulF 没问题!感谢您尝试提供帮助:)
  • 这是我刚刚找到的一些链接-不确定它们是否会帮助您-注意指定方向的方式:stackoverflow.com/questions/14247921/… docs.telerik.com/data-access/developers-guide/low-level -ado-??api/… c-sharpcorner.com/article/…


正如我的问题中提到的,我尝试将输出参数的 DbType 更改为 Int64。在查看时,我注意到有另一个(IN OUT)参数被声明为 DbType.Long。换一个的时候,我没有换另一个,所以显然还是报错了。

我得到的错误是:

ORA-06502: PL/SQL: numeric or value error: character string buffer too small

解决方法:将所有OracleDbType.Long参数改为OracleDbType.Int64。

事后看来,这是一个简单的答案。
我仍然不明白为什么这是一个问题。
Long 不应该与 Int64 相同/别名吗?

很抱歉打扰您,感谢您花时间尝试提供帮助。 :)
我希望有人可以用我的问题/答案解决他们的(类似)问题。

  • OracleDbType.Long 对应于 Oracle 数据类型 LONG,它用于最长 2 GB 的长字符串。请注意,数据类型 LONG 已被弃用多年,许多函数不支持此类型!另请参见 C#:Oracle 数据类型与 OracleDbType 等效
  • @WernfriedDomscheit 啊,谢谢,不知道。它确实解释了为什么它不起作用:)


来源:https://www.codenong.com/38918405/

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?