将一个字节数组传递给oracle存储过程

时间:2014-04-24 11:11:56

标签: c# sql oracle stored-procedures odp.net

使用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!,如果我在另一个数字上减少128,减去128,则可以正常工作!

我该怎么办?

2 个答案:

答案 0 :(得分:0)

试试这个:

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可能会起作用,因为它可能包含一个更大的数字。

答案 1 :(得分:0)

经过一些实验,我找到了解决方案。 首先,如果此数组包含大于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();
    }