只有一条记录从datagridview插入Oracle数据库

时间:2017-01-23 18:51:09

标签: c# datagridview oracle11gr2

我正在尝试从DataGridView读取数据并将其插入数据库。当一条记录在DataGridView中时,一切正常,但当DataGridView中有多条记录时,我只插入了一条记录而所有其他记录都未插入数据库。

我附上了Oracle功能代码以获取更多详细信息。

我认为自第一个table order以来函数引起的问题应该有一条记录,而子table order_details应该包含已购买商品的列表。因此,函数执行一次然后因第一个table (Order)上的主键异常而停止。

我不知道这是否正确但是如果它是正确的那么如何在一个事务中解决并保持事情发生所以所有事务都会成功,或者它将回滚所有事情之前已经完成了吗?

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;
                    }
                }

功能代码

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 个答案:

答案 0 :(得分:0)

这不一定是问题但是。 cmd.Parameters.Add(“:vORDER_ID”,OracleDbType.Int32,ParameterDirection.ReturnValue); 你没有在你的程序中使用orderid而你正在传递它。

其次, foreach实际上是为每个数据行循环吗?您没有提供足够的详细信息来帮助您进行调试。

第三,检查查询执行方法。我不认为它会返回vorder_id ExecuteNonQuery()

最后,vorderid将针对插入的每个记录进行更改,文本将仅显示插入的最后一个vorderid。