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 |
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,所以我希望有人能帮助我找到一个可行的答案。
正如我的问题中提到的,我尝试将输出参数的 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 相同/别名吗?
很抱歉打扰您,感谢您花时间尝试提供帮助。 :)
我希望有人可以用我的问题/答案解决他们的(类似)问题。