PLSQLAssociativeArray

Hi,
I've found a sample code on http://download-uk.oracle.com/docs/html/B10961_01/features.htm#1024855
I modified the code a little.
               OracleCommand cmd = new OracleCommand("begin MyPack.TestVarchar2(:1, :2, :3); end;", dbConn);
               OracleParameter Param1 = new OracleParameter();
               OracleParameter Param2 = new OracleParameter();
               OracleParameter Param3 = new OracleParameter();
               Param1.ParameterName = "1";
               Param1.ParameterName = "2";
               Param1.ParameterName = "3";
               Param1.OracleDbType = OracleDbType.Varchar2;
               Param2.OracleDbType = OracleDbType.Varchar2;
               Param3.OracleDbType = OracleDbType.Varchar2;
               Param1.Direction = ParameterDirection.Input;
               Param2.Direction = ParameterDirection.InputOutput;
               Param3.Direction = ParameterDirection.Output;
               // Specify that we are binding PL/SQL Associative Array
               Param1.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
               Param2.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
               Param3.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
               // Setup the values for PL/SQL Associative Array
               Param1.Value = new string[3]{"Papa",
                                                       "Mama",
                                                       "Gyerekek"};
               Param2.Value = new string[3]{"First Element",
                                                       "Second Element",
                                                       "Third Element"};
               Param3.Value = new string[3]{"1",
                                                       "2",
                                                       "3"};
               // Specify the maximum number of elements in the PL/SQL Associative Array
               Param1.Size = 3;
               Param2.Size = 3;
               Param3.Size = 3;
               // Setup the ArrayBindSize for Param1
               Param1.ArrayBindSize = new int[3]{13, 14, 13};
               cmd.Parameters.Add(Param1);
               cmd.Parameters.Add(Param2);
               cmd.Parameters.Add(Param3);
               // Setup the ArrayBindStatus for Param1
               Param1.ArrayBindStatus = new OracleParameterStatus[3]{
                                                                                     OracleParameterStatus.Success,
                                                                                     OracleParameterStatus.Success,
                                                                                     OracleParameterStatus.Success};
               // Setup the ArrayBindSize for Param2
               Param2.ArrayBindSize = new int[3]{20, 20, 20};
               // Setup the ArrayBindSize for Param3
               Param3.ArrayBindSize = new int[3]{20, 20, 20};
               // execute the cmd
               cmd.ExecuteNonQuery();
               //print out the parameter's values
               Console.WriteLine(Param2.ToString());
               Console.WriteLine(Param3.ToString());
In Oracle:
CREATE PACKAGE MYPACK AS
TYPE AssocArrayVarchar2_t is table of VARCHAR(20) index by BINARY_INTEGER;
PROCEDURE TestVarchar2(
Param1 IN AssocArrayVarchar2_t,
Param2 IN OUT AssocArrayVarchar2_t,
Param3 OUT AssocArrayVarchar2_t);
END MYPACK;
CREATE PACKAGE BODY MYPACK AS
PROCEDURE TestVarchar2(
Param1 IN AssocArrayVarchar2_t,
Param2 IN OUT AssocArrayVarchar2_t,
Param3 OUT AssocArrayVarchar2_t)
IS
i integer;
BEGIN
-- copy a few elements from y to z
Param3(1) := Param2(1);
Param3(2) := NULL;
Param3(3) := Param2(3);
-- copy all elements from x to y
Param2(1) := Param1(1);
Param2(2) := Param1(2);
Param2(3) := Param1(3);
FOR i IN 1..3 LOOP
insert into T1 values(i, Param2(i));
END LOOP;
FOR i IN 1..3 LOOP
select COL2 into Param2(i) from T2 where COL1 = i;
END LOOP;
END TestVarchar2;
END MYPACK;
But I don't get any character on console. WHY?

Hi,
From
http://download-west.oracle.com/docs/cd/B19306_01/win.102/b14307/featOraCommand.htm#BABBDHBB
<snippet>
// execute the cmd
cmd.ExecuteNonQuery();
//print out the parameter's values
Console.WriteLine("parameter values after executing the PL/SQL block");
for (int i = 0; i < 3; i++)
Console.WriteLine("Param2[{0}] = {1} ", i,
(cmd.Parameters[1].Value as Array).GetValue(i));
for (int i = 0; i < 3; i++)
Console.WriteLine("Param3[{0}] = {1} ", i,
(cmd.Parameters[2].Value as Array).GetValue(i));
</snippet>
Cheers,
Greg

Similar Messages

  • How can I pass an empty array to a parameter of type PLSQLAssociativeArray

    How can I pass an empty array to a parameter of type PLSQLAssociativeArray in VB? I defined the parameter like this
    Dim myArray() as String = new String() {}
    Dim myPara as new Oracle.DataAccess.Client.OracleCollectionType.PLSQLAssociativeArray
    myPara = 0
    myPara.Value = myArray
    When I execute my stored procedure giving the above parameter, I got error saying OracleParameter.Value is invalid.
    I have tried to give it the DBNull.Value, but it doesn't work either.
    Note: everything works fine as long as myArray has some item in there. I just wonder how I can make it works in case I have nothing.
    Thank you,

    How can I pass an empty array to a parameter of type PLSQLAssociativeArray in VB? I defined the parameter like this
    Dim myArray() as String = new String() {}
    Dim myPara as new Oracle.DataAccess.Client.OracleCollectionType.PLSQLAssociativeArray
    myPara = 0
    myPara.Value = myArray
    When I execute my stored procedure giving the above parameter, I got error saying OracleParameter.Value is invalid.
    I have tried to give it the DBNull.Value, but it doesn't work either.
    Note: everything works fine as long as myArray has some item in there. I just wonder how I can make it works in case I have nothing.
    Thank you,

  • ArrayBindSize and Size for PLSQLAssociativeArrays

    Hey there,
    I'm a complete newbie to ODP.NET and was hoping someone may be able to help with an issue. I basically need to call an SP from a VB.NET application and got as far as I could with the code below. The problem is that the parameters associates to this SP are all direction output. As a result, i'm having trouble trying to use the ArrayBindSize property and the Size property since I don't know what the number/size of the output from running the SP will exactly be? Does anyone see my predicament?
    I'm also seeing the following errors when I try to compile my application:
    Value of type '1-dimensional array of String' cannot be converted to '1-dimensional array of Integer' because 'String' is not derived from 'Integer'.
    Thanks in advance!
    Public Function RunSPReturnDS()
    Try
    Dim oraConnString As String = "Data Source=*****;User Id=******;Password=*****;"
    Dim oraConnection As New OracleConnection(oraConnString)
    oraConnection.Open()
    MessageBox.Show("Connection works!", "SUCCESS", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    oracleCMD = oraConnection.CreateCommand
    oracleCMD.CommandType = CommandType.StoredProcedure
    oracleCMD.CommandText = "OCDI_UTILITIES.GET_EXISS_TODAY"
    pStatus = New OracleParameter("P_STATUS", OracleDbType.Int32)
    pStatusText = New OracleParameter("P_STATUS_TEXT", OracleDbType.Varchar2)
    pRecReturned = New OracleParameter("P_RECORDS_RETURNED", OracleDbType.Int32)
    pMsgSysNameList = New OracleParameter("P_MSG_SYSTEM_NAME_LIST", OracleDbType.Varchar2)
    pMsgLastInDateTime = New OracleParameter("P_MSG_LAST_IN_DATETIME_LIST", OracleDbType.Date)
    pMsgGoodIn = New OracleParameter("P_MSG_GOOD_IN_LIST", OracleDbType.Int32)
    pMsgBadIn = New OracleParameter("P_MSG_BAD_IN_LIST", OracleDbType.Int32)
    pMsgLastOutDateTime = New OracleParameter("P_MSG_LAST_OUT_DATETIME_LIST", OracleDbType.Date)
    pMsgGoodOut = New OracleParameter("P_MSG_GOOD_OUT_LIST", OracleDbType.Int32)
    pMsgBadOut = New OracleParameter("P_MSG_BAD_OUT_LIST", OracleDbType.Int32)
    pStatus.CollectionType = OracleCollectionType.PLSQLAssociativeArray
    pStatusText.CollectionType = OracleCollectionType.PLSQLAssociativeArray
    pRecReturned.CollectionType = OracleCollectionType.PLSQLAssociativeArray
    pMsgSysNameList.CollectionType = OracleCollectionType.PLSQLAssociativeArray
    pMsgLastInDateTime.CollectionType = OracleCollectionType.PLSQLAssociativeArray
    pMsgGoodIn.CollectionType = OracleCollectionType.PLSQLAssociativeArray
    pMsgBadIn.CollectionType = OracleCollectionType.PLSQLAssociativeArray
    pMsgLastOutDateTime.CollectionType = OracleCollectionType.PLSQLAssociativeArray
    pMsgGoodOut.CollectionType = OracleCollectionType.PLSQLAssociativeArray
    pMsgBadOut.CollectionType = OracleCollectionType.PLSQLAssociativeArray
    pStatus.Direction = ParameterDirection.Output
    pStatusText.Direction = ParameterDirection.Output
    pRecReturned.Direction = ParameterDirection.Output
    pMsgSysNameList.Direction = ParameterDirection.Output
    pMsgLastInDateTime.Direction = ParameterDirection.Output
    pMsgGoodIn.Direction = ParameterDirection.Output
    pMsgBadIn.Direction = ParameterDirection.Output
    pMsgLastOutDateTime.Direction = ParameterDirection.Output
    pMsgGoodOut.Direction = ParameterDirection.Output
    pMsgBadOut.Direction = ParameterDirection.Output
    pStatus.Size = 10
    pStatusText.Size = 10
    pRecReturned.Size = 10
    pMsgSysNameList.Size = 10
    pMsgLastInDateTime.Size = 10
    pMsgGoodIn.Size = 10
    pMsgBadIn.Size = 10
    pMsgLastOutDateTime.Size = 10
    pMsgGoodOut.Size = 10
    pMsgBadOut.Size = 10
    'pStatus.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
    'pStatusText.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
    'pRecReturned.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
    'pMsgSysNameList.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
    'pMsgLastInDateTime.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
    'pMsgGoodIn.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
    'pMsgBadIn.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
    'pMsgLastOutDateTime.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
    'pMsgGoodOut.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
    'pMsgBadOut.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
    pStatus.ArrayBindSize = BindArraysToSizeInt()
    pStatusText.ArrayBindSize = BindArraysToSizeStr()
    pRecReturned.ArrayBindSize = BindArraysToSizeInt()
    pMsgSysNameList.ArrayBindSize = BindArraysToSizeStr()
    pMsgLastInDateTime.ArrayBindSize =
    pMsgGoodIn.ArrayBindSize = BindArraysToSizeInt()
    pMsgBadIn.ArrayBindSize = BindArraysToSizeInt()
    pMsgLastOutDateTime.ArrayBindSize =
    pMsgGoodOut.ArrayBindSize = BindArraysToSizeInt()
    pMsgBadOut.ArrayBindSize = BindArraysToSizeInt()
    oracleCMD.Parameters.Add(pStatus)
    oracleCMD.Parameters.Add(pStatusText)
    oracleCMD.Parameters.Add(pRecReturned)
    oracleCMD.Parameters.Add(pMsgSysNameList)
    oracleCMD.Parameters.Add(pMsgLastInDateTime)
    oracleCMD.Parameters.Add(pMsgGoodIn)
    oracleCMD.Parameters.Add(pMsgBadIn)
    oracleCMD.Parameters.Add(pMsgLastOutDateTime)
    oracleCMD.Parameters.Add(pMsgGoodOut)
    oracleCMD.Parameters.Add(pMsgBadOut)
    oracleCMD.ExecuteNonQuery()
    For i As Integer = 0 To pStatus.Size - 1
    Console.WriteLine(pStatus.Value(i))
    Next
    'ListView1.Items(3).SubItems.Add(P_STATUS)
    pStatus.Dispose()
    pStatusText.Dispose()
    pRecReturned.Dispose()
    pMsgSysNameList.Dispose()
    pMsgLastInDateTime.Dispose()
    pMsgGoodIn.Dispose()
    pMsgBadIn.Dispose()
    pMsgLastOutDateTime.Dispose()
    pMsgGoodOut.Dispose()
    pMsgBadOut.Dispose()
    oracleCMD.Dispose()
    oraConnection.Dispose()
    Catch ex As Exception
    MessageBox.Show(ex.Message.ToString(), "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
    End Function
    Private Function BindArraysToSizeInt() As Integer()
    Dim ArrBindSizeInt(collectionObjectsInt.Count - 1) As Integer
    For i As Integer = 0 To collectionObjectsInt.Count - 1
    ArrBindSizeInt(i) = collectionObjectsInt(i).ToString().Length
    Next i
    Return ArrBindSizeInt
    End Function
    Private Function BindArraysToSizeStr() As String()
    Dim ArrBindSizeStr(collectionObjectsStr.Count - 1) As String
    For i As Integer = 0 To collectionObjectsStr.Count - 1
    ArrBindSizeStr(i) = collectionObjectsStr(i).ToString().Length
    Next i
    Return ArrBindSizeStr
    End Function
    End Class

    Well - yes and no :-)
    When it comes to desktop displays then historically the term resolution has been used to describe only the Pixel Dimensions of the physical display and not the pixels per unit of measurement. Typically we don't bother any more about the screen PPI because its usually high enough not to be a problem.
    Projectors on the other hand display the image on varying screen sizes due to the distance from the screen. This makes resolution in terms of PPI important again. Yes, the projector has 'fixed' pixel dimensions but because the screen size varies the PPI will also vary. The further away the screen gets the larger the Pixels get and at some distance the image gets very 'pixellated' i.e you start to see the actual pixels.
    The other thing to keep in mind is that projectors are typically driven from a PC ( I guess we should include the Mac folks in this :-) )which may have a resolution (pixel dimensions) much higher than the projector. This may mean that you have to change the display properties on your PC to match or you may be lucky that the projector can re-sample for you.
    To answer the OP then the resolution in terms of PPI is more a question of controlling the distance between projector and screen and you need to check this visually although the venue may limit what you can actually do.
    In terms of Image Size (Pixel Dimensions) then I would say it depends on how critical you and your audience are, but to be honest there are probably other factors like colour, brightness and contrast that are going to be bigger issues than image sharpness.
    Colin #2

  • PLSQLAssociativeArray - ArraybindSize

    Hello all,
    Does anybody know the maximum size of an output parameter for ArrayBindSize when accessing a table of varchar2. And if so is their a way to set the limit?
    Right now I can go to a maximium of 2000 characters.
    thanks,
    Dhaval

    Actually odp.net limits us:
    "ArrayBindSize is used only for parameter types that have variable length such as Clob, Blob and Varchar2. The size is represented in bytes for binary datatypes and characters for the Unicode string types. The count for string types does not include the terminating character. The size is inferred from the actual size of the value, if it is not explicitly set. For an output parameter, the size of each value is set by ODP.NET. The ArrayBindSize property is ignored for fixed length datatypes. "
    But the doc doesn't state what size and whether if we can change the size or not. I know Microsoft's driver supports 4000 bytes (so I don't know why oracle would lessen the # of bytes returned).

  • How to define a output parameter in C# which maps to a PL/SQL table (odp)?

    OracleConnection objconnection = new OracleConnection(connectionstring);
    OracleCommand objcommand = objconnection.CreateCommand();
    objcommand.Connection = objconnection;
    objcommand.CommandText = "UBE_XSITE_PKG_V2.SP_DATAUPLOAD";
    objcommand.CommandType = CommandType.StoredProcedure;
    ListBox1.SelectedIndex = 0;
    OracleParameter prm1 = new OracleParameter("PI_LOT", OracleDbType.Varchar2);
    prm1.Direction = ParameterDirection.Input;
    prm1.Value = ListBox1.SelectedValue.ToString();
    objcommand.Parameters.Add(prm1);
    OracleParameter prm2 = new OracleParameter("PI_WS_OP", OracleDbType.Int32);
    prm2.Direction = ParameterDirection.Input;
    prm2.Value = (float)Int32.Parse(TextBox3.Text);
    objcommand.Parameters.Add(prm2);
    OracleParameter prm3 = new OracleParameter("PI_SOURCE_SITE", OracleDbType.Varchar2);
    prm3.Direction = ParameterDirection.Input;
    prm3.Value = DropDownList1.SelectedValue.ToString();
    objcommand.Parameters.Add(prm3);
    OracleParameter prm4 = new OracleParameter("PI_WS_FLAG", OracleDbType.Varchar2);
    prm4.Direction = ParameterDirection.Input;
    prm4.Value = DropDownList5.SelectedValue.ToString();
    objcommand.Parameters.Add(prm4);
    OracleParameter prm5 = new OracleParameter("PI_WS_QTY", OracleDbType.Int32);
    prm5.Direction = ParameterDirection.Input;
    prm5.Value = (float)Int32.Parse(TextBox2.Text);
    objcommand.Parameters.Add(prm5);
    OracleParameter prm6 = new OracleParameter("PO_EXCEPTIONS", OracleDbType.Varchar2);
    prm6.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    prm6.Direction = ParameterDirection.Output;
    prm6.IsNullable = true;
    prm6.Size = 4000;
    objcommand.Parameters.Add(prm6);
    objconnection.Open();
    objcommand.ExecuteNonQuery();
    objconnection.Close();

    Hi,
    You'll need to provide more detail about what the plsql type is exactly.
    However, you should check the ODP docs for examples, and it installs complete examples on your hard drive as well which will probably show you what you need to know.
    As of 11.1.6.20, ODP.NET supports user defined types. Prior to that, it also supports Associative Arrays (Index-by tables).
    Hope it helps
    Greg

  • PLS-00306:NET to call Oracle stored procedure,Use Array parameters

    Development Environment:Windows 2003 SP2+Oracle 10g
    . NET to call Oracle stored procedure, use an array of types of parameters
    Step1:(In the Oracle database define an array of types)
    CREATE OR REPLACE TYPE STRING_VARRAY AS VARRAY (1000) OF NVARCHAR2(255)
    OR
    CREATE OR REPLACE type string_array is table of nvarchar2(255)
    Step2:
    CREATE OR REPLACE PROCEDURE Test
    (i_test in string_varray,o_result out int)
    IS
    BEGIN
    o_result:=i_test.count;
    EXCEPTION
    WHEN NO_DATA_FOUND
    THEN
    NULL;
    WHEN OTHERS
    THEN
    o_result:=0;
    END arraytest;
    Step3:
    ODP.NET(Oracle 10g)
    OracleConnection conn = new OracleConnection("User Id=test;Password=test;Data Source=test");
    OracleCommand cmd = new OracleCommand("Test", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    string[] str = new string[2] { "11", "222" };
    cmd.ArrayBindCount=2;
    OracleParameter p1 = new OracleParameter("i_test", OracleDbType.NVarChar);
    p1.Direction = ParameterDirection.Input;
    p1.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    p1.Value = str;
    p1.ArrayBindSize=new int[2]{2,3};
    p1.ArrayBindStatus = new OracleParameterStatus[2]{
    OracleParameterStatus.Success,
    OracleParameterStatus.Success
    cmd.Parameters.Add(p1);
    OracleParameter p2 = new OracleParameter("o_result", OracleDbType.Int32);
    p2.Direction = ParameterDirection.Output;
    P2.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    p2.Value=0;
    cmd.Parameters.Add(p2);
    int i = 0;
    try
    conn.Open();
    cmd.ExecuteNonQuery();
    i =(int) p2.Value;
    catch (Exception ex)
    finally
    conn.Close();
    Error:
    Execution Failed:ORA-06550:Line 1,Column 7:
    PLS-00306:Test parameters when calling the number or types of errors
    ORA-06550:Line 1,Column 7:
    PL/SQL:Statement ignored

    Hi,
    See the answer in [this thread|http://forums.oracle.com/forums/thread.jspa?threadID=909564&tstart=0]
    Hope it helps,
    Greg

  • . NET to call Oracle stored procedure, use an array of types of parameters

    . NET to call Oracle stored procedure, use an array of types of parameters
    Step1:(In the Oracle database define an array of types)
    CREATE OR REPLACE TYPE STRING_VARRAY AS VARRAY (1000) OF NVARCHAR2(255)
    Step2:
    CREATE OR REPLACE PROCEDURE Test
    (i_test in string_varray,o_result out int)
    IS
    BEGIN
    o_result:=i_test.count;
    EXCEPTION
    WHEN NO_DATA_FOUND
    THEN
    NULL;
    WHEN OTHERS
    THEN
    o_result:=0;
    END arraytest;
    Step3:
    Use System.Data.OracleClient
    C# Code:
    OracleConnection conn = new OracleConnection("User Id=test;Password=test;Data Source=test");
    OracleCommand cmd = new OracleCommand("Test", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    string[] str = new string[] { "11", "22" };
    OracleParameter p1 = new OracleParameter("i_test", OracleType.NVarChar);
    p1.Direction = ParameterDirection.Input;
    p1.Value = str;
    cmd.Parameters.Add(p1);
    OracleParameter p2 = new OracleParameter("o_result", OracleType.Int32);
    p2.Direction = ParameterDirection.Output;
    cmd.Parameters.Add(p2);
    int i = 0;
    try
    conn.Open();
    cmd.ExecuteNonQuery();
    i =(int) p2.Value;
    catch (Exception ex)
    finally
    conn.Close();
    Error:
    Execution Failed:ORA-06550:Line 1,Column 7:
    PLS-00306:Test parameters when calling the number or types of errors
    ORA-06550:Line 1,Column 7:
    PL/SQL:Statement ignored
    Edited by: user10133982 on Jun 4, 2009 7:13 AM

    . NET to call Oracle stored procedure, use an array of types of parameters
    The use of ODP.net(Oracle 10g), the error is still the same
    Step1:(In the Oracle database define an array of types)
    CREATE OR REPLACE TYPE STRING_VARRAY AS VARRAY (1000) OF NVARCHAR2(255)
    Step2:
    CREATE OR REPLACE PROCEDURE Test
    (i_test in string_varray,o_result out int)
    IS
    BEGIN
    o_result:=i_test.count;
    EXCEPTION
    WHEN NO_DATA_FOUND
    THEN
    NULL;
    WHEN OTHERS
    THEN
    o_result:=0;
    END arraytest;
    Step3:
    ODP.NET(Oracle 10g)
    OracleConnection conn = new OracleConnection("User Id=test;Password=test;Data Source=test");
    OracleCommand cmd = new OracleCommand("Test", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    string[] str = new string[2] { "11", "222" };
    cmd.ArrayBindCount=2;
    OracleParameter p1 = new OracleParameter("i_test", OracleDbType.NVarChar);
    p1.Direction = ParameterDirection.Input;
    p1.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    p1.Value = str;
    p1.ArrayBindSize=new int[2]{2,3};
    p1.ArrayBindStatus = new OracleParameterStatus[2]{
    OracleParameterStatus.Success,
    OracleParameterStatus.Success
    cmd.Parameters.Add(p1);
    OracleParameter p2 = new OracleParameter("o_result", OracleDbType.Int32);
    p2.Direction = ParameterDirection.Output;
    P2.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    p2.Value=0;
    cmd.Parameters.Add(p2);
    int i = 0;
    try
    conn.Open();
    cmd.ExecuteNonQuery();
    i =(int) p2.Value;
    catch (Exception ex)
    finally
    conn.Close();
    Error:
    Execution Failed:ORA-06550:Line 1,Column 7:
    PLS-00306:Test parameters when calling the number or types of errors
    ORA-06550:Line 1,Column 7:
    PL/SQL:Statement ignored
    Edited by: user10133982 on Jun 5, 2009 7:48 AM

  • Problems binding array in C# to stored procedure.

    I'm having trouble trying to pass an array of ID's to a stored procedure that is expecting an array (listed the procedure definition below). My current interface doesn't return an error, but it also doesn't insert the proper id's.
    STORED PROCEDURE DEFINITION:
    TYPE source_ids IS TABLE OF wweb.DM_ASSOCIATIONS.source_id%TYPE INDEX BY PLS_INTEGER;
    PROCEDURE add_message_associations
    (p_dm_message_id IN wweb.dm_messages.dm_message_id%TYPE
    ,p_association_type IN wweb.dm_associations.association_type%TYPE
    ,p_sources IN source_ids
    ,p_create_user IN wweb.dm_associations.create_user%TYPE)
    .......variable definitions here...
    v_source_id := p_sources.First;
    WHILE v_source_id IS NOT NULL
    LOOP
    -- Check if this association already exists.
    -- If not add them.
    v_assoc_exists := 0;
    FOR r_chk IN
    (SELECT 1 AS assoc_exists_flag
    FROM dm_associations a
    WHERE a.dm_message_id = p_dm_message_id
    AND a.association_type = p_association_type
    AND a.source_id = v_source_id)
    LOOP
    v_assoc_exists := r_chk.assoc_exists_flag;
    END LOOP;
    IF v_assoc_exists = 0 THEN
    -- Add the association
    INSERT INTO wweb.dm_associations
    (dm_association_id
    ,dm_message_id
    ,association_type
    ,source_id
    ,source_column_name
    ,active_flag
    ,create_date
    ,create_user
    ,last_update_date
    ,last_update_user)
    VALUES
    (wweb.dm_associations_s.NEXTVAL
    ,p_dm_message_id
    ,p_association_type
    ,v_source_id
    ,v_source_column_name
    ,1
    ,SYSDATE
    ,p_create_user
    ,SYSDATE
    ,p_create_user);
    END IF;
    .......error handling here...
    C# CODE:
    OracleParameter[] param = new OracleParameter[4];
    param[0] = new OracleParameter("p_dm_message_id", OracleDbType.Long);
    param[1] = new OracleParameter("p_association_type", OracleDbType.Varchar2, 5);
    param[2] = new OracleParameter("p_sources", OracleDbType.Int32);
    param[3] = new OracleParameter("p_create_user", OracleDbType.Varchar2, 25);
    param[0].Value = 1;
    param[1].Value = "ER";
    param[2].Value = new Int32 [] {1, 172, 412, 7953};
    param[3].Value = "SVC-GDESAI";
    param[2].CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    param[2].Size = 4;
    param[2].ArrayBindStatus = new OracleParameterStatus[4]{OracleParameterStatus.Success, OracleParameterStatus.Success, OracleParameterStatus.Success, OracleParameterStatus.Success};
    cn = new OracleConnection(ConnectionString);
    cn.Open();
    OracleCommand cmd = new OracleCommand();
    cmd.Connection = cn;
    cmd.CommandText= "dynamic_messages_api.add_message_associations";
    cmd.CommandType= CommandType.StoredProcedure;
    foreach (OracleParameter p in param)
    if ((p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Input) && (p.Value == null || p.Value.ToString() == ""))
    p.Value = DBNull.Value;
    cmd.Parameters.Add(p);
    cmd.ExecuteNonQuery();
    This ran fine, and created four rows in the table, but the source id's were (1, 2, 3, 4) instead of (1, 172, 412, 7953) which were the ones I passed in.
    Does anyone know what I'm doing wrong here?
    Thanks,
    Gauranga

    Hi,
    I think you have a problem in you PL/SQL procedure. When you receive an array in the procedure, it is your responsibility to parse it explicitely with a loop or to bulk insert with a "forall" (implicit).
    For instance, here is an example of a procedure of mine. I don't catch exceptions as I want the C# calling code to know about them:
    The type t_* are defined like yours.
    procedure UpdateDistribDates(p_bannerid in t_bannerid,
    p_promonumber in t_promonumber,
    p_datenumber in t_datenumber,
    p_actualdate in t_actualdate ) is
    BEGIN
    -- First delete the existing dates in bulk
    FORALL I IN P_BANNERID.FIRST..P_BANNERID.LAST
    DELETE FROM PROMODISTRIBDATE
    WHERE BANNERID = P_BANNERID(I)
    AND PROMONUMBER = P_PROMONUMBER(I);
    -- Then, insert the values passed in arrays.
    FORALL I IN P_BANNERID.FIRST..P_BANNERID.LAST
    INSERT INTO PROMODISTRIBDATE
    (BANNERID,
    PROMONUMBER,
    DATENUMBER,
    ACTUALDATE)
    VALUES (P_BANNERID(I),
    P_PROMONUMBER(I),
    P_DATENUMBER(I),
    P_ACTUALDATE(I));
    END;
    As you can see, the FORALL keyword will process the arrays passed as any other PL/SQL array in one chunk.
    When you do the insert like:
    INSERT INTO wweb.dm_associations
    (dm_association_id
    ,dm_message_id
    ,association_type
    ,source_id
    ,source_column_name
    ,active_flag
    ,create_date
    ,create_user
    ,last_update_date
    ,last_update_user)
    VALUES
    (wweb.dm_associations_s.NEXTVAL
    ,p_dm_message_id
    ,p_association_type
    ,v_source_id
    ,v_source_column_name
    ,1
    ,SYSDATE
    ,p_create_user
    ,SYSDATE
    ,p_create_user);
    In source_id, you insert the index of the table, not the value of the field.
    I would suggest you completely rewrite this procedure by using the explicit loop like this:
    1/ Explicit loop
    FOR i IN 1 .. p_sources.COUNT LOOP
    -- Check the existence
    EXIST_FLAG := 0;
    BEGIN
    SELECT 1
    INTO EXIST_FLAG
    FROM ...
    WHERE ...
    AND a.source_id = p_source(i) <-- You are parsing here
    AND ...
    EXCEPTION
    WHEN OTHERS THEN -- Nothing was found
    EXIST_FLAG := 0;
    END;
    IF (EXIST_FLAG = 1)
    INSERT INTO wweb.dm_associations
    (dm_association_id
    ,dm_message_id
    ,association_type
    ,source_id
    ,source_column_name
    ,active_flag
    ,create_date
    ,create_user
    ,last_update_date
    ,last_update_user)
    VALUES
    (wweb.dm_associations_s.NEXTVAL
    ,p_dm_message_id
    ,p_association_type
    ,p_source(i) <-- You parse here
    END IF;
    END LOOP;
    2/ Implicit loop and bulk insert
    You would need to completely review the logic and build an array that maps exactly the row of the table you are trying to insert into. Parse the array and check for the existence of your entry, delete the row in memory when not found, then, after the loop do a bulk insert with a "forall".
    Hope it helps,
    Patrice

  • PL/SQL function: using parameter of type PL/SQL record?

    Hi,
    Is it possible to call the following function from within c#:
    CREATE FUNCTION myfunc (par1 table%ROWTYPE) RETURN <sometype>
    IS ...
    Can ODP.Net handle rowtype records? I have found no hints in the manuals.
    thanks,
    stephan

    Hello Stephan,
    Can ODP.Net handle rowtype records?ODP does not currently support %rowtype (or object) types.
    PLSQLAssociativeArray is the only supported collection type at this time.
    - Mark

  • Pass values to Guid collection/array parameter for anonymous pl/sql block

    The following code pops the System.ArgumentException: Invalid parameter binding
    Parameter name: p_userguids
    at Oracle.DataAccess.Client.OracleParameter.GetBindingSize_Raw(Int32 idx)
    at Oracle.DataAccess.Client.OracleParameter.PreBind_Raw()
    at Oracle.DataAccess.Client.OracleParameter.PreBind(OracleConnection conn, IntPtr errCtx, Int32 arraySize)
    at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()
    Any help or advice ?
    anonymous pl/sql block text:
    DECLARE
    TYPE t_guidtable IS TABLE OF RAW(16);
    p_userguids t_guidtable;
    BEGIN
    DELETE testTable where groupname=:groupname;
    INSERT INTO testTable (userguid, groupname)
    SELECT column_value, :groupname FROM TABLE(p_userguids);
    END;
    c# code:
    public static void SetGroupUsers(string group, List<Guid> users)
    OracleConnection conn = Database.ConnectionEssentus;
    try
    conn.Open();
    OracleCommand sqlCmd = new OracleCommand();
    sqlCmd.CommandText = sqls["SetGroupUsers"]; // above anonymous block
    sqlCmd.Connection = conn;
    sqlCmd.BindByName = true;
    OracleParameter p_guidCollection = sqlCmd.Parameters.Add("p_userguids", OracleDbType.Raw);
    p_guidCollection.Size = users.Count;
    p_guidCollection.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    p_guidCollection.UdtTypeName = "t_guidtable";
    p_guidCollection.Value = users.ToArray();
    sqlCmd.Parameters.Add("groupname", OracleDbType.Varchar2, 30).Value = group;
    sqlCmd.ExecuteNonQuery();
    catch(Exception ex)
    System.Diagnostics.Debug.WriteLine(ex.ToString());
    finally
    conn.Close();
    }

    New question,
    How can I select records using "in" condition clause likes the following sentence?
    SELECT userguid, firstname, lastname FROM UserTable WHERE userguid in (SELECT column_value FROM TABLE(p_userguids))
    I tried using PIPE ROW like this, but ORACLE said "PLS-00629: PIPE statement cannot be used in non-pipelined functions"
    FOR i in p_userguids.first .. p_userguids.last
    LOOP
    SELECT userguid, firstname, lastname INTO l_userrecord FROM UserTable WHERE userguid=p_userguids(i);
    PIPE ROW(l_userrecord);
    END LOOP;

  • PL/SQL Associative Array as INPUT Parameter

    Hi,
    Just wondering if anyone out there has a good example of how to get VB.NET (using ODP.NET 9.2.0.4) to pass an Associative Array as an Input parameter to a stored procedure (not for bulk binds)? Specifically, I'm looking for an example of how a VB Strong Typed Collection would be passed through the PLSQLAssociativeArray Collection Type.
    I've managed to get a test to work by passing a 1-D String Array through the ODP.NET layer to the PL/SQL AssociativeArray parameter. But I've had zero success trying to get the Collection from VB through ODP.NET.
    Thanks in advance for any help.
    Todd.

    For example, if I wanted to return a list of customer ids and names into A PLSQL Associative Array, how would I do it. I know how to return a list of customer ids into a PLSQL associative aray using the code below but I have to specify the maximum number of elements and the maximum size of each of the elements. Is there any way around this?
    Dim prmOutCustomerIdList As New OracleParameter
    With prmOutCustomerIdList
    .ParameterName = "oCustomerIdList"
    .CollectionType = OracleCollectionType.PLSQLAssociativeArray
    .OracleDbType = OracleDbType.Varchar2
    .Direction = ParameterDirection.Output
    .Size = 5
    .ArrayBindSize = New Integer(4) {10, 10, 10, 10, 10}
    End With

  • Return pl/sql array to C#

    First of all, my goal is to return an array that I've defined back to C#.
    Here is the type that I've defined:
    create or replace type EMPARRAY is VARRAY(20) of VARCHAR2(30)here is the function I'm trying to call
    create or replace function getEmpArray
    Return EMPARRAY as 
      V_data EMPARRAY := EMPARRAY();
    Cursor student_test is
      SELECT student_id
      FROM students;
    Begin
      For stu_rec In student_test
      Loop
        V_data.extend;
        V_data(V_data.count) := stu_rec.student_id;
      End loop;
      Return V_data;
    END;Now, I've installed the ODP.NET connector from oracle and am attempting to get that array returned but I'm having issues. Here is my c# code:
            public void test_Click(Object obj, EventArgs ea)
                //create connection string
                String strConnection = "data source=foo;user id=foo;password=foo;";
                using (OracleConnection conn = new OracleConnection(strConnection))
                    OracleCommand objCmd = new OracleCommand();
                    objCmd.Connection = conn;
                    objCmd.CommandText = "getEmpArray";
                    objCmd.CommandType = CommandType.StoredProcedure;
                    OracleParameter returnValue = new OracleParameter("retVal", OracleCollectionType.PLSQLAssociativeArray);
                    returnValue.Size = 100;
                    returnValue.Direction = ParameterDirection.ReturnValue;
                    objCmd.Parameters.Add(returnValue);
                    try
                        conn.Open();
                        Console.WriteLine("Connection Successful");
                    catch (OracleException e)
                        MessageBox.Show(e.Message, "Oracle Exception");
                }//end using
            }//end test ClickWhat I have compiles fine but when I fire the click event, it gives me an error saying that Object reference not set to an instance of an object. It points to this line:
    OracleParameter returnValue = new OracleParameter("retVal", OracleCollectionType.PLSQLAssociativeArray);So any suggestions on how I should go about doing this? I'm probably completely off base here so any help would be appreciated.

    Hi,
    You're using a User Defined Type (UDT), not a PLSLQ Associative Array.
    ODP.NET has UDT support starting in version 11.1.0.6.21, and there are examples that install with it in your Oracle\odp.net\samples\2.x\UDT folder if you already have that version. It's generally easiest if you use Oracle Developer Tools to generate the class code, and you can get that in the same bundle as 11.1.0.6.21 odp.
    Alternatively, since you're just returning an array of scalar types, you could switch to a PLSQL Associative Array for that which has been supported for quite a few versions now. You'd define the type inside the procedure instead.. type EMPARRAY is table of VARCHAR2(30) index by binary_integer . There is an example that installs with ODP in your Oracle\odp.net\samples\2.xx\AssocArray folder.
    Hope it helps,
    Greg
    Edited by: gdarling on Jul 8, 2009 7:59 AM
    However, since you already have a cursor in your stored procedure, why bother converting it to something else anyway? Just return a REF CURSOR. See your ODP.NET\samples\2.x\RefCursor folder for examples.

  • Pass array to oracle stored procedure

    I have such a problem: I have to pass array to stored procedure, so I declare type:
    create type tNumberArray as table of number
    and create procedure:
    create or replace procedure proc_1 (in_param in tNumberArray) as
    .... BODY OF PROCEDURE ...
    when I call this procedure from C# like this:
    int []pParam = new int[3] {1,2,3};
    OracleCommand cmd = new OracleCommand("proc_1", dbConn);
    cmd.CommandType = CommandType.StoredProcedure;
    OracleParameter param14 = new OracleParameter("param", OracleDbType.Decimal);
    param14.Value = pParam;
    param14.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    param14.Size = 3;
    param14.Direction = ParameterDirection.Input;
    cmd.Parameters.Add(param14);
    cmd.ExecuteNonQuery();
    an error occures. It say that there invalid number or type of parameters.
    But when I declare both type and procedure in a package everything goes fine.
    What is the matter? Did anybody have the same problem?

    Not I got next problem:
    when I cannot pass parameter to stored procedure and get array fro it. In other words returning array from procedure and passing some input parameters to it does not word!
    Does anybody know why it happens?

  • Problem with OracleParameter.Clone()

    I've found a strange behaviour in ODP.
    I've created a parameter collection where i've added all the parameters.
    then i simply create a copy of the collection in the command object:
    //adds all parameters that existed in collection of parameters
    foreach (OracleParameter oParam in oParamCol)
    oCmd.Parameters.Add(oParam.Clone());
    }//foreach
    Everything worked ok until I create a parameter with:
    CollectionType = OracleCollectionType.PLSQLAssociativeArray;
    When i clone the object it looses this property value!!!
    And i think it looses some more AssociativeArray properties that i've added to the parameter.
    Is this a BUG in ODP.Net?
    Can someone give me an explanation to this strage behaviour?

    For best chances of getting a reply, you may want to post it to ODP.NET forum (ODP.NET

  • Strange ORA-01044 error

    Hi Guys,
    I'm getting a very strange ORA-01044 error:
    Oracle.DataAccess.Client.OracleException ORA-01044: size 87160000 of buffer bound to variable exceeds maximum 288212783965667328    at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx pOpoSqlValCtx, Object src, String procedure)*
    at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx pOpoSqlValCtx, Object src)*
    at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()
    As you can see, the buffer size does not exceed the maximum stated, yet it is still causing an exception.
    Some background.. A new parameter has been added to a stored proc that was originally working fine, this new parameter is an associative array of numbers.
    On the ODP.Net side, I create a parameter that has a collection type of "*PLSQLAssociativeArray*" and Oracle DB Type of "*Int32*".
    Any ideas as to what might be causing this problem?

    Hi,
    What db version?
    There is an older bug where this error would be raised if the requested buffer size exceeded the granule size of the SGA. That was from the 9.2 timeframe as I recall.
    Regards,
    Mark

Maybe you are looking for

  • Is it possible to use one apple ID for my two private MacBooks?

    anybody there who can answer this question right now? Thanks

  • 2 Macbook Pros don't see D-Link signal help please

    Hoping someone might be able to help. I have two macbook pros, and at work both connect without problem to my Dlink DIR300 router (the second I power up it connects...) The problem begins when I get home, and both macbooks don't see the signal for th

  • How to make a single record datablock?

    Hi all, I got a data-entry form (9i) that will input a record one at a time and commit before entering another record. I try to set the block as single-record to yes but it gives error, and after checking with help, I understand that it can not work

  • Selling PSE 8... New Owner Issues?

    Hi - Ever since I got Lightroom 3 I found it does what I need so... what issues are there if I sell my PSE 8 to someone?  The new owner can use the license key, yes? Is the new owner somehow limited? Thank-you

  • Presentation cant be opened

    1. While working on one of the presentations, my ipad became slow. So I saved the presentation and restarted my IPAD. After the restart when I tried opening the presentation, i got an error message "Presentation cant be opened". I immediately went to