2009-01-08 96 views
2

如下所示的代码,我想从OracleParameter对象获取值。它的数据类型是日期时间。如何从OracleParameter对象获取值

... 

Dim cmd As New OracleCommand("stored_proc_name", cnObject) 
cmd.Parameters.Add("tran_date_out", OracleDbType.Date, ParameterDirection.Output) 

... 

cmd.ExecuteNonQuery() 

... 

Dim tranDate As Date 
tranDate = cmd.Parameters("tran_date_out").Value 

当我将值赋给tranDate变量时,出现错误。但是如果我按照以下方式编码,我只能得到日期。

tranDate = CDate(cmd.Parameters("tran_date_out").Value.ToString) 

那么我怎么能得到的值日期和时间tranDate变量?

回答

5

关闭我的头顶部时,OracleParameter.Value将out参数分配给奇怪的Oracle盒装类型。这似乎是一个完全可怕的设计或甲骨文的一部分......但不是返回字符串,你会得到OracleString等

每种Oracle类型都有一个.Value具有系统类型,但他们当然不会“T都实现一个共同的接口暴露这一点,所以我所做的就是基本上写一个方法拆箱类型:

/// <summary> 
/// The need for this method is highly annoying. 
/// When Oracle sets its output parameters, the OracleParameter.Value property 
/// is set to an internal Oracle type, not its equivelant System type. 
/// For example, strings are returned as OracleString, DBNull is returned 
/// as OracleNull, blobs are returned as OracleBinary, etc... 
/// So these Oracle types need unboxed back to their normal system types. 
/// </summary> 
/// <param name="oracleType">Oracle type to unbox.</param> 
/// <returns></returns> 
internal static object UnBoxOracleType(object oracleType) 
{ 
    if (oracleType == null) 
    return null; 

    Type T = oracleType.GetType(); 
    if (T == typeof(OracleString)) 
    { 
    if (((OracleString)oracleType).IsNull) 
     return null; 
    return ((OracleString)oracleType).Value; 
    } 
    else if (T == typeof(OracleDecimal)) 
    { 
    if (((OracleDecimal)oracleType).IsNull) 
     return null; 
    return ((OracleDecimal)oracleType).Value; 
    } 
    else if (T == typeof(OracleBinary)) 
    { 
    if (((OracleBinary)oracleType).IsNull) 
     return null; 
    return ((OracleBinary)oracleType).Value; 
    } 
    else if (T == typeof(OracleBlob)) 
    { 
    if (((OracleBlob)oracleType).IsNull) 
     return null; 
    return ((OracleBlob)oracleType).Value; 
    } 
    else if (T == typeof(OracleDate)) 
    { 
    if (((OracleDate)oracleType).IsNull) 
     return null; 
    return ((OracleDate)oracleType).Value; 
    } 
    else if (T == typeof(OracleTimeStamp)) 
    { 
    if (((OracleTimeStamp)oracleType).IsNull) 
     return null; 
    return ((OracleTimeStamp)oracleType).Value; 
    } 
    else // not sure how to handle these. 
    return oracleType; 
} 

这可能不是最干净的解决方案,但...这是快速和肮脏,并且为我工作。

只需将OracleParameter.Value传递给此方法即可。


其实,在回答之前,我可能只有一半的人会读到你的问题。我认为Oracle的日期类型只包含不是时间的日期。

神谕型时间戳既有的日期和时间。

希望有帮助! :)

+0

我真的很讨厌那近7年后的今天,这仍然是最好的答案我可以找到这个问题... – Rozwel 2015-12-07 21:56:53

0

我没有经过大量测试,但这里是使用反射CodingWithSpike的回答不太详细的版本...

public static object UnBoxOracleType(object oracleType) { 
    if(oracleType==null) { 
     return null; 
    } 

    if((bool)oracleType.GetType().GetProperty("IsNull").GetValue(oracleType)) { 
     return null; 
    } 
    return oracleType.GetType().GetProperty("Value").GetValue(oracleType); 
} 

同样你逝去的OracleParameter.Value此方法。

或者一个更类型安全的版本,你可以这样做:

public static object GetValue(OracleParameter param) { 
    if(param == null || param.Value==null) { 
     return null; 
    } 

    var oracleType=param.Value; 

    if((bool)oracleType.GetType().GetProperty("IsNull").GetValue(oracleType)) { 
     return null; 
    } 
    return oracleType.GetType().GetProperty("Value").GetValue(oracleType); 
} 

在这种情况下,您会通过Oracle参数本身得到值回。这也可以实现,如果你需要的话扩展方法...