Vb.net 从Visual Basic调用Oracle函数

Vb.net 从Visual Basic调用Oracle函数,vb.net,oracle,plsql,casting,Vb.net,Oracle,Plsql,Casting,不确定为什么我的代码在从VB调用时返回错误,但是PLSQL(Oracle)中的类似代码没有返回错误 Oracle功能: CREATE OR REPLACE FUNCTION GET_CUST_STRING_FROM_DB (pcustid NUMBER) RETURN VARCHAR2 AS returnstring VARCHAR2(200); vcustomer customer%rowtype; BEGIN SELECT * INTO vcustomer F

不确定为什么我的代码在从VB调用时返回错误,但是PLSQL(Oracle)中的类似代码没有返回错误

Oracle功能:

CREATE OR REPLACE FUNCTION GET_CUST_STRING_FROM_DB (pcustid NUMBER) RETURN VARCHAR2 AS
    returnstring VARCHAR2(200);
    vcustomer customer%rowtype;
BEGIN
    SELECT * INTO vcustomer
    FROM customer
    WHERE custid = pcustid;

    returnstring := 'CustID: ' || vcustomer.custid || ' Name: ' || vcustomer.custname || ' Status: ' || vcustomer.status || ' SalesYTD: ' || vcustomer.sales_ytd;
    RETURN returnstring;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        RAISE_APPLICATION_ERROR(-20021,'Error: Customer ID not found');
    WHEN OTHERS THEN
        RAISE_APPLICATION_ERROR(-20000,SQLERRM);
END;
/
Oracle呼叫:

set serveroutput on;

begin
    dbms_output.put_line(get_cust_string_from_db(1));
end;
Oracle输出:

Anonymous Block Completed
CustID: 1 Name: Colin Smith Status: OK SalesYTD: 0
VB代码:

Private Sub GetCustString()
    Try
        Dim connOracle As Oracle.DataAccess.Client.OracleConnection
        Dim commOracle As New Oracle.DataAccess.Client.OracleCommand
        Dim paramOracle As Oracle.DataAccess.Client.OracleParameter

        connOracle = CreateConnection()
        commOracle.Connection = connOracle
        commOracle.CommandType = CommandType.StoredProcedure
        commOracle.CommandText = "GET_CUST_STRING_FROM_DB"

        paramOracle = New Oracle.DataAccess.Client.OracleParameter
        paramOracle.ParameterName = "pcustid"
        paramOracle.DbType = DbType.Int16
        paramOracle.Value = tbGetCustStringCustID.Text
        paramOracle.Direction = ParameterDirection.Input
        commOracle.Parameters.Add(paramOracle)

        paramOracle = New Oracle.DataAccess.Client.OracleParameter
        paramOracle.ParameterName = "pReturnValue"
        paramOracle.DbType = DbType.String
        paramOracle.Direction = ParameterDirection.ReturnValue
        commOracle.Parameters.Add(paramOracle)

        lbOutput.Items.Add(commOracle.Parameters.Item("pcustid").Value)
        lbOutput.Items.Add("--------------------------------------------")
        lbOutput.Items.Add("Getting Details for CustID " & tbGetCustStringCustID.Text)

        connOracle.Open()
        commOracle.ExecuteNonQuery()
        Dim vStr As String
        vStr = commOracle.Parameters.Item("pReturnValue").Value.ToString
        lbOutput.Items.Add(vStr)
        connOracle.Close()
    Catch ex As Exception
        lbOutput.Items.Add(ex.Message)
    End Try
End Sub
VB输出:

1
-----------------------------------------
Getting Details for CustID 1
ORA-20021: Error: Customer ID not found
所以我不确定为什么会发生这种情况。 我尝试捕捉参数的值,并确保它是实际的整数而不是字符串。数据库中不存在CustID 1,并且已提交

有什么想法吗?

您必须指定返回值的(最大)大小,即

paramOracle.Size = 200

除了指定返回值的大小之外,您还需要首先添加返回值参数

Private Sub GetCustString()
    Try
        Dim connOracle As Oracle.DataAccess.Client.OracleConnection
        Dim commOracle As New Oracle.DataAccess.Client.OracleCommand
        Dim paramOracle As Oracle.DataAccess.Client.OracleParameter

        connOracle = CreateConnection()
        commOracle.Connection = connOracle
        commOracle.CommandType = CommandType.StoredProcedure
        commOracle.CommandText = "GET_CUST_STRING_FROM_DB"

        paramOracle = New Oracle.DataAccess.Client.OracleParameter
        paramOracle.ParameterName = "pReturnValue"
        paramOracle.DbType = DbType.String
        paramOracle.Size = 200
        paramOracle.Direction = ParameterDirection.ReturnValue
        commOracle.Parameters.Add(paramOracle)

        paramOracle = New Oracle.DataAccess.Client.OracleParameter
        paramOracle.ParameterName = "pcustid"
        paramOracle.DbType = DbType.Int16
        paramOracle.Value = tbGetCustStringCustID.Text
        paramOracle.Direction = ParameterDirection.Input
        commOracle.Parameters.Add(paramOracle)

        lbOutput.Items.Add(commOracle.Parameters.Item("pcustid").Value)
        lbOutput.Items.Add("--------------------------------------------")
        lbOutput.Items.Add("Getting Details for CustID " & tbGetCustStringCustID.Text)

        connOracle.Open()
        commOracle.ExecuteNonQuery()
        Dim vStr As String
        vStr = commOracle.Parameters.Item("pReturnValue").Value.ToString
        lbOutput.Items.Add(vStr)
        connOracle.Close()
    Catch ex As Exception
        lbOutput.Items.Add(ex.Message)
    End Try
End Sub

谢谢@Ciarán!秩序确实重要。我刚刚学到了一些我不想知道的东西。松了一口气…但也有点难过。