将字节数组传递给 oracle 存储过程
Posted
技术标签:
【中文标题】将字节数组传递给 oracle 存储过程【英文标题】:Pass a byte array to oracle stored procedure 【发布时间】:2014-04-24 11:11:56 【问题描述】:我在使用 odp.net 将字节数组作为输入参数传递给 Oracle 存储过程时遇到了一个问题。
这里是存储过程签名:
SOMEPROCEDURE(session IN NUMBER, data IN RAW)
这里是C#代码,调用过程:
var cmd = new OracleCommand("SOME_PROCEDURE", _connection);
cmd.CommandType = CommandType.StoredProcedure;
var bt = new byte[]1,68,0,83,128,1;
OracleParameter sessionId = new OracleParameter("dbSessionId", OracleDbType.Decimal, new OracleDecimal(_dbSessionId), ParameterDirection.Input);
OracleParameter data = new OracleParameter("statusData", OracleDbType.Raw, new OracleBinary(bt), ParameterDirection.Input);
cmd.Parameters.Add(sessionId);
cmd.Parameters.Add(data);
cmd.ExecuteNonQuery();
此代码失败(存储过程抛出异常,无法获取数据),因为字节数组中有数字128!,如果我在另一个数字上chage 128,减去128,它可以正常工作!
我该怎么办?
【问题讨论】:
【参考方案1】:试试这个:
var cmd = new OracleCommand("SOME_PROCEDURE", _connection);
cmd.CommandType = CommandType.StoredProcedure;
int[] bt = new int[]1,68,0,83,128,1;
OracleParameter sessionId = new OracleParameter("dbSessionId", OracleDbType.Decimal, new OracleDecimal(_dbSessionId), ParameterDirection.Input);
OracleParameter data = new OracleParameter("statusData", OracleDbType.Raw, new OracleBinary(bt), ParameterDirection.Input);
cmd.Parameters.Add(sessionId);
cmd.Parameters.Add(data);
cmd.ExecuteNonQuery();
这可能是因为一个字节太小,一个 int 可能会起作用,因为它可能包含一个更大的数字。
【讨论】:
没有OracleBinary
构造函数将Int32
数组作为参数,也没有从byte
数组到int
数组的隐式对话。
我不知道,您可以尝试制作 2 个字节数组。
字节不小,字节是8位无符号整数,所以它的最大值是255。看来,oracle数据行不能包含无符号8位值。【参考方案2】:
经过一些实验,我找到了解决方案。 首先,如果该数组包含大于 127 的值,则不能通过 odp.net 传递给存储过程的字节数组。
所以,解决方案: 1. 创建包装程序
procedure SOME_PROCEDURE_WRAPPER (p_session_id in number,
p_data in varchar2)
is
v_data raw(1024);
rawdata raw(1024);
rawlen number;
hex varchar2(32760);
i number;
begin
rawlen := length(p_data);
i := 1;
while i <= rawlen-1
loop
hex := substrb(p_data,i,2);
rawdata := rawdata || HEXTORAW(hex);
i := i + 2;
end loop;
SOME_PROCEDURE(p_session_id , rawdata);
end;
2 然后需要这样修改C#代码:
var cmd = new OracleCommand("SOME_PROCEDURE_WRAPPER", _connection);
cmd.CommandType = CommandType.StoredProcedure;
string @string = statusData.ToHexString();
OracleParameter sessionId = new OracleParameter("dbSessionId", OracleDbType.Decimal, new OracleDecimal(_dbSessionId), ParameterDirection.Input);
OracleParameter data = new OracleParameter("statusData", OracleDbType.Varchar2,@string.Length, new OracleString(@string), ParameterDirection.Input);
cmd.Parameters.Add(sessionId);
cmd.Parameters.Add(data);
cmd.ExecuteNonQuery();
在哪里
public static string ToHexString(this byte[] bytes)
if(bytes == null || bytes.Length == null)
return string.Empty;
StringBuilder hexStringBuilder = new StringBuilder();
foreach (byte @byte in bytes)
hexStringBuilder.Append(@byte.ToString("X2"));
return hexStringBuilder.ToString();
【讨论】:
以上是关于将字节数组传递给 oracle 存储过程的主要内容,如果未能解决你的问题,请参考以下文章