Only one record inserted into Oracle database from datagridview

巧了我就是萌 提交于 2019-12-12 04:33:00

问题


I am trying to read data from DataGridView and insert it into database. Everything works fine when one record is in the DataGridView, but when there is more than one record within the DataGridView I got only one record inserted and all other records are not inserted into database.

I have attached the Oracle function code for more details.

I think the issue caused by function since the first table order should have one record and the sub table order_details should have the list of purchased items. So the function execute once and then stop because of primary key exception on the first table (Order).

I don't know if that is right but in case it is right then how to solve and keep thing happen in one transaction so all transaction will success, or it will rollback all things has been done before?

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, "حدث خطاء", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }

function Code

CREATE OR REPLACE FUNCTION F_INS_Order_Data (P_CUSTOMER_ID     IN NUMBER,
                                                                                       P_ORDER_NOTE       IN VARCHAR2,
                                                                                       P_PRODUCT_ID        IN NUMBER,
                                                                                       P_UNIT_PRICE         IN NUMBER,
                                                                                       P_QUANTITY           IN NUMBER,
                                                                                       P_DISCOUNT           IN NUMBER,
                                                                                       P_ORDER_STATUS  IN VARCHAR2,
                                                                                       P_ITEM_NOTE         IN VARCHAR2)
   RETURN NUMBER
IS
   VOrder_Id      NUMBER;                --ORDER_ID Filled by trigger
   vCreated_by   VARCHAR2 (64)         := 'SYSTEM';
   vCreated_On   DATE                        := SYSDATE;

   sql_stmt           VARCHAR2 (4000);
   ERR_CODE      VARCHAR2(64);
   ERR_MSG       VARCHAR2(1024);

BEGIN

    SAVEPOINT Setp1;

    sql_stmt := 'INSERT INTO orders (ORDER_ID,
                                                          CUSTOMER_ID,
                                                          NOTES,
                                                          CREATED_BY,
                                                          CREATED_ON)
                                            VALUES (NULL,                       --ORDER_ID Filled by trigger
                                                          :PCUSTOMER_ID,    --CUSTOMER_ID
                                                          :POrderNote,            --NOTES
                                                          :PCREATED_BY,       --CREATED_BY
                                                          :PCREATED_ON)     --CREATED_ON
                      RETURNING ORDER_ID INTO :vORDER_ID';

    EXECUTE IMMEDIATE sql_stmt USING P_CUSTOMER_ID,
                                                                   P_ORDER_NOTE,
                                                                   vCreated_by,
                                                                   vCreated_ON
                      RETURNING INTO vORDER_ID;

    --DBMS_OUTPUT.PUT_LINE (sql_stmt);    /* For Testing Purpose */


    sql_stmt:='INSERT INTO ORDER_DETAILS (ORDER_ID,
                                                                           PRODUCT_ID,
                                                                           UNIT_PRICE,
                                                                           QUANTITY,
                                                                           DISCOUNT,
                                                                           ORDER_STATUS,
                                                                           NOTES,
                                                                           CREATED_BY,
                                                                           CREATED_ON)
                                                           VALUES ( :PvORDER_ID,              --ORDER_ID,
                                                                           :PPRODUCT_ID,          --PRODUCT_ID
                                                                           :PUNIT_PRICE,           --UNIT_PRICE
                                                                           :PQUANTITY,             --QUANTITY
                                                                           :PDISCOUNT,             --DISCOUNT
                                                                           :PORDER_STATUS,    --ORDER_STATUS
                                                                           :PItem_Note,                 --NOTES
                                                                           :PCREATED_BY,          --CREATED_BY
                                                                           :PCREATED_ON         --CREATED_ON
                                                                          )';

    EXECUTE IMMEDIATE sql_stmt USING vORDER_ID,
                                                                   P_PRODUCT_ID,
                                                                   P_UNIT_PRICE,
                                                                   P_QUANTITY,
                                                                   P_DISCOUNT,
                                                                   P_ORDER_STATUS,
                                                                   P_ITEM_NOTE,
                                                                   vCreated_by,
                                                                   vCreated_On;

   --DBMS_OUTPUT.PUT_LINE (sql_stmt);    /* For Testing Purpose */

   RETURN (VOrder_Id);

EXCEPTION WHEN OTHERS THEN 

    ROLLBACK TO Setp1;

    ERR_CODE := SQLCODE;
    ERR_MSG := SUBSTR(SQLERRM, 1, 1024);

    sql_stmt := F_INS_ERROR_LOG(SYSDATE,                        --P_ERROR_TIME,
                                                       vCreated_by,                    --P_USER_ID,
                                                       'F_INS_Order_Data',      --P_PROGRAM_UNIT,
                                                       NULL,                              --P_ERROR_LOCATION,
                                                       NULL,                             --P_KEY_DATA_DESC,
                                                       ERR_CODE,                    --P_ERROR_CODE,
                                                       ERR_MSG);                    --P_ERROR_MSG)';

RETURN -1;

END F_INS_Order_Data;
/

回答1:


This is not necessarily the issue but. cmd.Parameters.Add(":vORDER_ID", OracleDbType.Int32, ParameterDirection.ReturnValue); You are not using orderid in your proceuder and you are passing it in.

Second, Is the foreach actually looping for each data row? You have not provided enough detail to help you debug this.

Third, Check the query execution method. I dont think its going to return the vorder_id ExecuteNonQuery()

Finally, the vorderid is going to change for each record inserted and the text would only show the last vorderid inserted.



来源:https://stackoverflow.com/questions/41813535/only-one-record-inserted-into-oracle-database-from-datagridview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!