1

我有一个在某些情况下返回 null 的存储过程。当我ToString()返回 null 时,它会以字符串而不是空字符串的形式返回“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

上面的代码返回“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

最后,上面的代码返回一个正确的空字符串,但是它在所有情况下都会这样做,无论是否应该返回一些东西。

我过去经常使用这样的存储过程,但是它们总是在所有情况下都返回一个值。我不太确定如何处理这个空值。我不想先检查包含“null”的字符串,因为这有点hacky,我想知道将来我做错了什么。

4

2 回答 2

1

我认为,您正在使用 ODP.NET。在这种情况下,而不是这个

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会返回你Oracle null。如果您将返回值转换为 Oracle 类型,现在您可以访问 .Net 类型的值。当您使用时,您将adoCmd.Parameters(0).Value.ToString()获得 Oracle 实现ToString,它只返回一些单词null

当您使用 odp.net Oracle 参数、存储过程或带返回值的参数化查询时要记住这一点 - 没关系,就像这里

Dim sql as String = "insert into table ...) returning fld1 into :1"

有趣的观察:SqlClient是非法的Parameters(0).Value = Nothing。它想要DBNull.Value。在 ODP.NET 中不是问题。它需要任何 -Nothing或/和DBNull.Value

当您使用时OracleReader,尤其是通过IDataReader- 这不是问题。Reader("fld1")将返回 .net 类型。

Dim r As IdataReader = cmd.ExecuteReader...
Dim i As Integer = reader("fld1")

您需要注意的是将 Oracle DB 类型与 .NET 匹配。问题是,它们不匹配。如果您声明表字段Number(9),它将返回 .netIntegerNumber(9)不够大以适应.net Integer.MaxValue。如果声明表字段Number(10)Reader("fld1")将返回Long。因此,.netInteger介于Number(9)和之间Number(10)。您需要使用转换

 Dim i As Integer = convert.ToInt32(reader("fld1"))
于 2015-08-07T21:39:30.593 回答
0

事实证明,将这条线添加到两个参数之间可以解决问题。

adoCmd.Parameters(0).DbType = DbType.String
于 2015-08-07T18:46:24.933 回答