ошибка при чтении данных из DataGridView и вставка в базу данных оракула

Я пытаюсь вставить данные из DataGridView в базу данных оракула для одной записи, все работает нормально, но когда в DataGridView есть более одной строки, я получаю следующее сообщение об ошибке:

ora-06550 строка 1 столбец 15:

pls-00306 неправильное число или типы аргументов при вызове «F_INS_ORDER_DATA»

ora-06550 строка 1 столбец 7:

Оператор pl/sql игнорируется

Я попытался

  1. Проверьте количество параметров, но они в порядке, так как одна запись успешно вставлена

  2. нет неправильного типа параметра, но они в порядке, потому что одна запись успешно вставлена

  3. Я проверил, находятся ли аргументы в неправильном порядке, но они в порядке также потому, что одна запись успешно вставлена

Код:

string connstr = @"Data Source=orcl; User Id=user; password=pwd;";

string insertcmdtxt = @"F_INS_ORDER_DATA";   

using (OracleConnection conn = new OracleConnection(connstr))
using (OracleCommand cmd = new OracleCommand(insertcmdtxt, conn))
{
    try
    {
        conn.Open();

        cmd.CommandType = CommandType.StoredProcedure;

        cmd.CommandText = insertcmdtxt;

        cmd.Parameters.Add(":vORDER_ID", OracleDbType.Int32, ParameterDirection.ReturnValue);

        foreach (DataGridViewRow Row in DGV_INVOICE.Rows)
        {
            cmd.Parameters.Add(new OracleParameter(":P_CUSTOMER_ID", OracleDbType.Int32)).Value     = TB_CUSTOMER_ID.Text;
            cmd.Parameters.Add(new OracleParameter(":P_ORDER_NOTE", OracleDbType.Varchar2)).Value   = TB_ORDER_NOTE.Text;

            cmd.Parameters.Add(new OracleParameter(":P_PRODUCT_ID", OracleDbType.Int32)).Value      = Row.Cells[DGV_INVOICE.Columns["DGV_PRODUCT_ID"].Index].Value;
            cmd.Parameters.Add(new OracleParameter(":P_UNIT_PRICE", OracleDbType.Int32)).Value      = Row.Cells[DGV_INVOICE.Columns["DGV_UNIT_PRICE"].Index].Value;
            cmd.Parameters.Add(new OracleParameter(":P_QUANTITY", OracleDbType.Int32)).Value        = Row.Cells[DGV_INVOICE.Columns["DGV_QUANTITY"].Index].Value;
            cmd.Parameters.Add(new OracleParameter(":P_DISCOUNT", OracleDbType.Int32)).Value        = Row.Cells[DGV_INVOICE.Columns["DGV_DISCOUNT"].Index].Value;
            cmd.Parameters.Add(new OracleParameter(":P_ORDER_STATUS", OracleDbType.Varchar2)).Value = '1';
            cmd.Parameters.Add(new OracleParameter(":P_ITEM_NOTE", OracleDbType.Varchar2)).Value    = Row.Cells[DGV_INVOICE.Columns["DGV_ITEM_NOTE"].Index].Value;
        }

        cmd.ExecuteNonQuery();

        TB_INVOICE_ID.Text = (cmd.Parameters[":vORDER_ID"].Value).ToString();
    }
    catch (Exception EX)
    {
        MessageBox.Show(EX.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }
}
}'

Обновление кода

После тестирования предложения от друзей ниже

Теперь я не получаю никаких ошибок, но если в базе данных более одной строки, я нашел только одну вставленную запись.

string connstr = @"Data Source=orcl; User Id=user; password=pwd;";
                string insertcmdtxt = @"F_INS_ORDER_DATA";  

                using (OracleConnection conn = new OracleConnection(connstr))
                using (OracleCommand cmd = new OracleCommand(insertcmdtxt, conn))
                {
                    try
                    {
                        conn.Open();

                        cmd.CommandType = CommandType.StoredProcedure;

                        cmd.CommandText = insertcmdtxt;

                        foreach (DataGridViewRow Row in DGV_INVOICE.Rows)
                        {
                            cmd.Parameters.Clear();

                            cmd.Parameters.Add(":vORDER_ID", OracleDbType.Int32, ParameterDirection.ReturnValue);

                            cmd.Parameters.Add(new OracleParameter(":P_CUSTOMER_ID", OracleDbType.Int32)).Value     = TB_CUSTOMER_ID.Text;
                            cmd.Parameters.Add(new OracleParameter(":P_ORDER_NOTE", OracleDbType.Varchar2)).Value   = TB_ORDER_NOTE.Text;

                            cmd.Parameters.Add(new OracleParameter(":P_PRODUCT_ID", OracleDbType.Int32)).Value      = Row.Cells[DGV_INVOICE.Columns["DGV_PRODUCT_ID"].Index].Value;
                            cmd.Parameters.Add(new OracleParameter(":P_UNIT_PRICE", OracleDbType.Int32)).Value      = Row.Cells[DGV_INVOICE.Columns["DGV_UNIT_PRICE"].Index].Value;
                            cmd.Parameters.Add(new OracleParameter(":P_QUANTITY", OracleDbType.Int32)).Value        = Row.Cells[DGV_INVOICE.Columns["DGV_QUANTITY"].Index].Value;
                            cmd.Parameters.Add(new OracleParameter(":P_DISCOUNT", OracleDbType.Int32)).Value        = Row.Cells[DGV_INVOICE.Columns["DGV_DISCOUNT"].Index].Value;
                            cmd.Parameters.Add(new OracleParameter(":P_ORDER_STATUS", OracleDbType.Varchar2)).Value = '1';
                            cmd.Parameters.Add(new OracleParameter(":P_ITEM_NOTE", OracleDbType.Varchar2)).Value    = Row.Cells[DGV_INVOICE.Columns["DGV_ITEM_NOTE"].Index].Value;
                        }

                        cmd.ExecuteNonQuery();                        

                        TB_INVOICE_ID.Text = (cmd.Parameters[":vORDER_ID"].Value).ToString();
                    }
                    catch (Exception EX)
                    {
                        MessageBox.Show(EX.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }

person sam    schedule 23.01.2017    source источник
comment
Вы продолжаете добавлять параметры снова для каждой строки. Нужно сделать это только один раз, а затем в цикле просто изменить значения параметров (и включить ExecuteNonQuery() в цикл).   -  person OldProgrammer    schedule 23.01.2017
comment
Как говорит @OldProgrammer, плюс либо очистите свои параметры в верхней части цикла (cmd.Parameters.Clear();), либо сделайте объявления перед циклом и измените значения внутри цикла (cmd.Parameters[":P_PRODUCT_ID"].Value = Row.Cells...;).   -  person Steve Greene    schedule 23.01.2017
comment
@SteveGreene, тогда что лучше очистить параметры или изменить значения?   -  person sam    schedule 23.01.2017
comment
@OldProgrammer большое спасибо   -  person sam    schedule 23.01.2017
comment
Я бы не подумал, что это будет проблемой производительности, поэтому я бы просто сделал очистку.   -  person Steve Greene    schedule 23.01.2017
comment
@SteveGreene, тогда очистка параметров будет проще cmd.Parameters.Clear() в начале цикла я получаю сообщение об ошибке: ora-06550, строка 1, столбец 7: pls-00221: 'F_INS_ORDER_DATA' не является процедурой или не определена ora-06550, строка 1, столбец 7: Оператор pl/sql игнорируется   -  person sam    schedule 23.01.2017
comment
Переместите vORDER_ID после очистки.   -  person Steve Greene    schedule 23.01.2017
comment
@SteveGreene вставляет одну запись, когда в DataGridView имеется более одной записи, пытался использовать MessageBox.Show(DGV_INVOICE.RowCount.ToString());, чтобы увидеть счет, если он правильный, он показывает правильный счет, но кажется, что он не зацикливается, он вставляет одну запись   -  person sam    schedule 23.01.2017
comment
@SteveGreene зацикливается дважды, поскольку сообщение появляется дважды, когда есть две записи, но вставляет одну запись ... так что это зацикливается, но я не знаю, почему он не вставляет одну запись   -  person sam    schedule 23.01.2017
comment
@OldProgrammer есть идеи по поводу проблемы?   -  person sam    schedule 23.01.2017
comment
Если вы внесли изменения в свой код, как было предложено, и возникла другая проблема, откройте новый вопрос с помощью минимальный воспроизводимый пример. Спасибо.   -  person OldProgrammer    schedule 23.01.2017
comment
@OldProgrammer спасибо, пожалуйста, если вы не возражаете, посмотрите здесь заголовок stackoverflow.com/questions/41813535/ Я думаю, я нашел проблему, но мне нужна небольшая помощь, спасибо заранее   -  person sam    schedule 23.01.2017