使用12c客户端截断的存储过程OUTPUT VARCHAR2值
我正在使用oracle 11g 。 我的存储过程返回varchar2
但它的值被oracle client
截断。 以下是我的代码:
if ((ds != null) && (ds.Tables.Count > 0)) { foreach (DataRow rw in ds.Tables[0].Rows) { OracleParameter param = new OracleParameter((rw["argument_name"]).ToString(), GetOracleType(rw["data_type"].ToString().ToUpper())); param.Direction = GetParameterDirection((rw["in_out"]).ToString().ToUpper()); discoveryCommand.Parameters.Add(param); if (param.Direction == ParameterDirection.Output && param.OracleType == OracleType.VarChar) { param.Size = 4000; } } }
我将param.size
增加到4000
但仍然会截断值。 对此有什么解决方案吗? 在服务器上我有Oracle 12c 。 我需要在我的项目中不更新oracle客户端版本的情况下获得解决方案,因为某些原因不允许这样做。
以下是SP。 我修改它以返回硬编码值。 还是同样的问题。
PROCEDURE access_level ( p_emp_id IN employees.emp_id%TYPE, p_id IN NUMBER, p_type VARCHAR2, p_access_level OUT VARCHAR2 ) IS BEGIN p_access_level := 'X' || 'RO' || 'RW'; END IF;
我无法为连接到服务器12.1.0.1.0的客户端版本11.2.0.1.0重现您的问题。 这是Oracle 12c客户端截断输出变量的已知情况 ,但是如果您使用的是11g版本的客户端,则不应该是您的情况。
我使用了以下测试表和存储过程:
CREATE TABLE TEST_TABLE ( ID NUMBER(11) NOT NULL, NAME VARCHAR2(256), CONSTRAINT TEST_TABLE_PK PRIMARY KEY (ID) ) / INSERT INTO TEST_TABLE(ID, NAME) VALUES(1, 'Some test data') / CREATE PROCEDURE TEST_PROCEDURE ( P_ID OUT NUMBER, P_NAME OUT VARCHAR2 ) AS BEGIN SELECT ID, NAME INTO P_ID, P_NAME FROM TEST_TABLE; END;
以下是正确提取数据的客户端代码:
using (OracleConnection connection = new OracleConnection()) { connection.ConnectionString = ConfigurationManager.ConnectionStrings["TestDatabase"].ConnectionString; connection.Open(); using (OracleCommand command = connection.CreateCommand()) { command.CommandText = "TEST_PROCEDURE"; command.CommandType = CommandType.StoredProcedure; OracleParameter param1 = new OracleParameter("P_ID", OracleType.Number); param1.Direction = ParameterDirection.Output; command.Parameters.Add(param1); OracleParameter param2 = new OracleParameter("P_NAME", OracleType.VarChar); param2.Size = 4000; param2.Direction = ParameterDirection.Output; command.Parameters.Add(param2); using (command.ExecuteReader()) { Console.WriteLine($"Output: [{param2.Value}]"); } } }
要继续提出您的问题,请执行以下操作:
- 如果可以创建上面的测试表和存储过程,并检查如何使用上面的代码获取字符串数据。
-
如果由于某种原因不可能,请提供以下信息:
- 被称为存储过程的完整代码
- 从事存储过程的所有表的DDL
- 获取数据的完整客户端代码
魔鬼总是在细节中。 我们应该理解您的情况与上述工作示例代码的不同之处。
我尝试通过迁移到ODP.NET
来解决问题,因为System.Data.OracleClient
已被Microsoft
弃用,如此处所述,但问题未得到解决。 以下是问题的解决方法:
- 机器
12.1.0.2.2
上安装了Oracle客户端版本 -
Output parameter truncation
错误在Oracle
文档中提到为Bug21616079
-
Oracle
在此处的Oracle
文档中提到了12.2.0.1.0
版本中的修复程序。 - 因此,从
12.1.0.2.2
升级到12.2.0.1.0
版本为我解决了这个问题,因为Oracle
仅在此版本中提供了修复,这在我在上面第3点提供链接的官方Oracle
文档中提到过。
- 仅将少数列的数据复制到另一个数据表
- ADO.NET:安全地为所有VarChar参数指定SqlParameter.Size的-1?
- 无法绑定多部分标识符“System.Data.DataRowView”
- 使用SqlBulkCopy插入数据时出错
- 如何从Sql表中检索DataColumn.DefaultValue?
- 将DBNull.Value和Empty文本框值传递给数据库
- 如何通过SqlConnection获取上次执行的SQL查询?
- 通过使用语句和Dispose为DataTable,SqlConnection,SqlCommand和SqlDataAdapter清理资源
- INSERT INTO Firebird如何自动增加主键?