OracleCommand StoredProcedure 返回 "null" 而不是 DBNull
OracleCommand StoredProcedure returning "null" instead of DBNull
我有一个存储过程,在某些情况下 returns 为空。当我 ToString()
空值时,它 returns "null" 作为字符串而不是空字符串,但是如果我不使用 .ToString()
方法,它会导致错误。
Public Function ReturnValue(ByVal lngId As Long) As String
Dim adoCmd As New OracleCommand
Dim strReturn As String = ""
With adoCmd
.CommandText = "BUS_TEST.ReturnValue"
.CommandType = CommandType.StoredProcedure
.Parameters.Add("return", OracleDbType.Char, 256, strReturn, ParameterDirection.ReturnValue)
.Parameters.Add("lngId", OracleDbType.Double, lngId, ParameterDirection.Input)
End With
objSalUtil.ExecFunc(ocEWBConnection, adoCmd, "ReturnValue")
Return adoCmd.Parameters(0).Value.ToString
End Function
以上代码returns"null"
Public Function ReturnValue(ByVal lngId As Long) As String
Dim adoCmd As New OracleCommand
Dim strReturn As String = ""
With adoCmd
.CommandText = "BUS_TEST.ReturnValue"
.CommandType = CommandType.StoredProcedure
.Parameters.Add("return", OracleDbType.Char, 256, strReturn, ParameterDirection.ReturnValue)
.Parameters.Add("lngId", OracleDbType.Double, lngId, ParameterDirection.Input)
End With
objSalUtil.ExecFunc(ocEWBConnection, adoCmd, "ReturnValue")
Return adoCmd.Parameters(0).Value
End Function
以上代码导致 InvalidCastException:从类型 'OracleString' 到类型 'String' 的转换无效。
Public Function ReturnValue(ByVal lngId As Long) As String
Dim adoCmd As New OracleCommand
Dim strReturn As String = ""
With adoCmd
.CommandText = "BUS_TEST.ReturnValue"
.CommandType = CommandType.StoredProcedure
.Parameters.Add("return", OracleDbType.Char, 256, strReturn, ParameterDirection.ReturnValue)
.Parameters.Add("lngId", OracleDbType.Double, lngId, ParameterDirection.Input)
End With
objSalUtil.ExecFunc(ocEWBConnection, adoCmd, "ReturnValue")
Return strReturn
End Function
最后,上面的代码 returns 是一个正确的空字符串,但它在所有情况下都是如此,无论是否应该返回某些内容。
我过去经常使用这样的存储过程,但是在所有情况下它们总是返回一个值。我不太确定如何处理这个空值。我不想先检查包含 "null" 的字符串,因为这有点老套,而且我想知道我做错了什么。
原来在两个参数之间添加这一行解决了问题。
adoCmd.Parameters(0).DbType = DbType.String
我认为,您正在使用 ODP.NET。在这种情况下,而不是 this
Return adoCmd.Parameters(0).Value
你这样做
Dim oraStr As OracleString = CType(adoCmd.Parameters(0).Value, OracleString)
Return oraStr.Value ' return .net string
发生的事情是,这个 adoCmd.Parameters(0).Value
return 是你 Oracle null
。如果您将 return 值转换为 Oracle 类型,现在您可以访问 .Net 类型的值。当您使用 adoCmd.Parameters(0).Value.ToString()
时,您会得到 ToString
的 Oracle 实现,它只是 return 一些词 null
。
当您使用 odp.net Oracle 参数、存储过程或具有 return 值的参数化查询时,请记住这一点 - 没关系,就像这里
Dim sql as String = "insert into table ...) returning fld1 into :1"
Interesting Observation: In SqlClient
this is illegal Parameters(0).Value = Nothing
. It wants DBNull.Value
. In ODP.NET is not a problem. It takes any - Nothing
or/and DBNull.Value
当您使用 OracleReader
时,尤其是通过 IDataReader
- 这不是问题。 Reader("fld1")
将 return .net 类型。
Dim r As IdataReader = cmd.ExecuteReader...
Dim i As Integer = reader("fld1")
您需要注意的是将 Oracle 数据库类型与 .NET 相匹配。问题是,它们不匹配。如果您声明 table 字段 Number(9)
它将 return .net Integer
但 Number(9)
不够大以适应 Integer.MaxValue
。如果声明 table 字段 Number(10)
,Reader("fld1")
将 return Long
。因此,.net Integer
介于 Number(9)
和 Number(10)
之间。你需要使用 convert
Dim i As Integer = convert.ToInt32(reader("fld1"))
我有一个存储过程,在某些情况下 returns 为空。当我 ToString()
空值时,它 returns "null" 作为字符串而不是空字符串,但是如果我不使用 .ToString()
方法,它会导致错误。
Public Function ReturnValue(ByVal lngId As Long) As String
Dim adoCmd As New OracleCommand
Dim strReturn As String = ""
With adoCmd
.CommandText = "BUS_TEST.ReturnValue"
.CommandType = CommandType.StoredProcedure
.Parameters.Add("return", OracleDbType.Char, 256, strReturn, ParameterDirection.ReturnValue)
.Parameters.Add("lngId", OracleDbType.Double, lngId, ParameterDirection.Input)
End With
objSalUtil.ExecFunc(ocEWBConnection, adoCmd, "ReturnValue")
Return adoCmd.Parameters(0).Value.ToString
End Function
以上代码returns"null"
Public Function ReturnValue(ByVal lngId As Long) As String
Dim adoCmd As New OracleCommand
Dim strReturn As String = ""
With adoCmd
.CommandText = "BUS_TEST.ReturnValue"
.CommandType = CommandType.StoredProcedure
.Parameters.Add("return", OracleDbType.Char, 256, strReturn, ParameterDirection.ReturnValue)
.Parameters.Add("lngId", OracleDbType.Double, lngId, ParameterDirection.Input)
End With
objSalUtil.ExecFunc(ocEWBConnection, adoCmd, "ReturnValue")
Return adoCmd.Parameters(0).Value
End Function
以上代码导致 InvalidCastException:从类型 'OracleString' 到类型 'String' 的转换无效。
Public Function ReturnValue(ByVal lngId As Long) As String
Dim adoCmd As New OracleCommand
Dim strReturn As String = ""
With adoCmd
.CommandText = "BUS_TEST.ReturnValue"
.CommandType = CommandType.StoredProcedure
.Parameters.Add("return", OracleDbType.Char, 256, strReturn, ParameterDirection.ReturnValue)
.Parameters.Add("lngId", OracleDbType.Double, lngId, ParameterDirection.Input)
End With
objSalUtil.ExecFunc(ocEWBConnection, adoCmd, "ReturnValue")
Return strReturn
End Function
最后,上面的代码 returns 是一个正确的空字符串,但它在所有情况下都是如此,无论是否应该返回某些内容。
我过去经常使用这样的存储过程,但是在所有情况下它们总是返回一个值。我不太确定如何处理这个空值。我不想先检查包含 "null" 的字符串,因为这有点老套,而且我想知道我做错了什么。
原来在两个参数之间添加这一行解决了问题。
adoCmd.Parameters(0).DbType = DbType.String
我认为,您正在使用 ODP.NET。在这种情况下,而不是 this
Return adoCmd.Parameters(0).Value
你这样做
Dim oraStr As OracleString = CType(adoCmd.Parameters(0).Value, OracleString)
Return oraStr.Value ' return .net string
发生的事情是,这个 adoCmd.Parameters(0).Value
return 是你 Oracle null
。如果您将 return 值转换为 Oracle 类型,现在您可以访问 .Net 类型的值。当您使用 adoCmd.Parameters(0).Value.ToString()
时,您会得到 ToString
的 Oracle 实现,它只是 return 一些词 null
。
当您使用 odp.net Oracle 参数、存储过程或具有 return 值的参数化查询时,请记住这一点 - 没关系,就像这里
Dim sql as String = "insert into table ...) returning fld1 into :1"
Interesting Observation: In
SqlClient
this is illegalParameters(0).Value = Nothing
. It wantsDBNull.Value
. In ODP.NET is not a problem. It takes any -Nothing
or/andDBNull.Value
当您使用 OracleReader
时,尤其是通过 IDataReader
- 这不是问题。 Reader("fld1")
将 return .net 类型。
Dim r As IdataReader = cmd.ExecuteReader...
Dim i As Integer = reader("fld1")
您需要注意的是将 Oracle 数据库类型与 .NET 相匹配。问题是,它们不匹配。如果您声明 table 字段 Number(9)
它将 return .net Integer
但 Number(9)
不够大以适应 Integer.MaxValue
。如果声明 table 字段 Number(10)
,Reader("fld1")
将 return Long
。因此,.net Integer
介于 Number(9)
和 Number(10)
之间。你需要使用 convert
Dim i As Integer = convert.ToInt32(reader("fld1"))