0

データベースに 3 つのテーブルにデータを挿入するストアド プロシージャがあります。プロシージャは正しくコンパイルされます。サンプルデータを使用して PL/SQL DEVELOPER ツールでテストしましたが、正常に動作しています。

ストアド プロシージャのコードでは、no をカウントする変数 successCnt1 を使用しました。成功した挿入ステートメントの。この変数は、successCnt に割り当てられます。この変数の値はコード ビハインドから取得しています。successCnt == 0 の場合、エラーが表示されます。

問題は、プロシージャの背後にある C# コードから呼び出すと、successCnt == 0 が返されることです。どこが間違っているのか教えてください!! 前もって感謝します。

テーブル スキーマ:

TBLTRAIN スキーマ: {TRAINID (VARCHAR2(5)), DATE1 (DATE) , AC2SEAT (NUMBER) ,AC3SEAT (NUMBER) , SLEEPERSEAT (NUMBER) ,ACCHAIRCARSEAT (NUMBER) ,SECONDSEAT (NUMBER)}

TBLTRAINFARE スキーマ: {TRAINID (VARCHAR2(5)), CLASS (VARCHAR2(5)), FARE (NUMBER)}

TBLTRAINDETAIL スキーマ: {TRAINID (VARCHAR2(5)) , FROM1 (VARCHAR2(15)), TO1 (VARCHAR2(15)) , TRAINNAME (VARCHAR2(15)) }

手順:

CREATE OR REPLACE PROCEDURE TrainInsertByParameter (p_ac2seat   in number,
                                       p_ac3seat  in number,
                                       p_ccseat  in number,
                                       p_sleeperseat  in number,
                                       p_secondseat  in number,
                                       p_date1      in date,
                                       p_trainid   in varchar2,
                                       p_fare in number,
                                       p_fromplace in varchar2,
                                       p_toplace in varchar2,
                                       p_class in varchar2,
                                       p_trainname in varchar2,
                                       p_successCnt  out number)  IS
successCnt1 number(6) NOT NULL := 0;
rowUpdated1 number(6) NOT NULL := 0;
rowUpdated2 number(6) NOT NULL := 0;
rowUpdated3 number(6) NOT NULL := 0;

BEGIN
  SAVEPOINT before;

  INSERT INTO tbltrain (ac2seat,ac3seat,acchaircarseat,sleeperseat,secondseat,date1,trainid) VALUES(p_ac2seat,p_ac3seat,p_ccseat,p_sleeperseat,p_secondseat,p_date1,p_trainid);


rowUpdated1 := SQL%RowCount;
successCnt1 := successCnt1 + 1;

   dbms_output.put_line('Successful Insertion tbltrain. count ='||successCnt1);
   dbms_output.put_line('Successful Insertion tbltrain. Row Updated ='||rowUpdated1);

  INSERT INTO tbltraindetail (trainid,trainname,from1,to1) VALUES(p_trainid,p_trainname,p_fromplace,p_toplace);


rowUpdated2 := SQL%RowCount;
successCnt1 := successCnt1 + 1;

 dbms_output.put_line('Successful Insertion tbltraindetail. count ='||successCnt1);
 dbms_output.put_line('Successful Insertion tbltraindetail. Row Updated= '||rowUpdated2);

INSERT INTO tbltrainfare(trainid,class,fare) VALUES (p_trainid,p_class,p_fare);

rowUpdated3 := SQL%RowCount;
successCnt1 := successCnt1 + 1;
p_successCnt := successCnt1;

 COMMIT;

 dbms_output.put_line('Successful Insertion tbltrainfare. count ='||p_successCnt);
 dbms_output.put_line('Successful Insertion tbltrainfare. Row Updated= '||rowUpdated3);

  EXCEPTION
    WHEN Others THEN
      successCnt1 := 0;
      p_successCnt := successCnt1;
      dbms_output.put_line('An error has occured. count ='||p_successCnt);

    ROLLBACK TO before;

END;

C# コード ビハインドのコードの呼び出し (Microsoft Visual Studio を使用)

OracleConnection con1 = new OracleConnection();
                 con1.ConnectionString = ConfigurationManager.ConnectionStrings["myConnectionStringOracle"].ConnectionString;

            Int32 fare = Convert.ToInt32(txtFare.Value);
            String date1 = txtDate.Value.ToString();
            String class1 = ddlClass.SelectedItem.Text.ToString();
            String fromplace = txtFromPlace.Text.ToString();
            String toplace = txtToPlace.Text.ToString();
            String trainid = txtId1.Text.ToString();
            String trainname = txtTrainName.Text.ToString();
            Int32 ac2seat = Convert.ToInt32(txtAc2TierSeat.Value);
            Int32 ac3seat = Convert.ToInt32(txtAc3TierSeat.Value);
            Int32 ccseat = Convert.ToInt32(txtAcChairCarSeat.Value);
            Int32 sleeperseat = Convert.ToInt32(txtSleeperSeat.Value);
            Int32 secondseat = Convert.ToInt32(txtSecondSeat.Value);
            Int32 SuccessCnt;

 OracleCommand cmd = new OracleCommand();
                    cmd.Connection = con1;
                    cmd.CommandText = "TrainInsertByParameter";
                    cmd.CommandType = CommandType.StoredProcedure;


                    cmd.Parameters.Add("p_ac2seat", OracleType.Number).Value = ac2seat;
                    cmd.Parameters.Add("p_ac3seat", OracleType.Number).Value = ac3seat;
                    cmd.Parameters.Add("p_ccseat", OracleType.Number).Value = ccseat;
                    cmd.Parameters.Add("p_sleeperseat", OracleType.Number).Value = sleeperseat;
                    cmd.Parameters.Add("p_secondseat", OracleType.Number).Value = secondseat;
                    cmd.Parameters.Add("p_date1", OracleType.DateTime).Value = date1;
                    cmd.Parameters.Add("p_trainid", OracleType.VarChar).Value = trainid;
                    cmd.Parameters.Add("p_fare", OracleType.Number).Value = fare;
                    cmd.Parameters.Add("p_fromplace", OracleType.VarChar).Value = fromplace;
                    cmd.Parameters.Add("p_toplace", OracleType.VarChar).Value = toplace;
                    cmd.Parameters.Add("p_class", OracleType.VarChar).Value = class1;
                    cmd.Parameters.Add("p_trainname", OracleType.VarChar).Value = trainname;


                    cmd.Parameters.Add("p_successCnt", OracleType.Number).Direction = ParameterDirection.Output;


                    try
                    {


                        cmd.ExecuteNonQuery();
                        SuccessCnt = Convert.ToInt32(cmd.Parameters["p_successCnt"].Value);

                        if (SuccessCnt == 0)
                        {
                            Page.ClientScript.RegisterStartupScript(this.GetType(), "Window", "alert('An error has occured. No data has been inserted. Please try again with valid data');", true);

                        }
                        else if (SuccessCnt > 0)
                        {
                            Page.ClientScript.RegisterStartupScript(this.GetType(), "Window", "alert('Data has been inserted successfully.');", true);
                        }

                    }
                    catch (Exception ex)
                    {

                    }

私の問題はここにあります:デバッグ中、if-else ブロック (try{} ブロック内) では、プロシージャが p_successCnt ==0 を返すため、コントロールは常に if(SuccessCnt==0){} セクションに移動します。プロシージャが p_successCnt ==3 を返す必要があるため、コントロールが else if(SuccessCnt > 0){} ブロックに移動することを期待しています

4

2 に答える 2

0

プロシージャーに出力パラメーターを追加して、プロシージャーの実行時に発生する例外から生じる SQLCODE および SQLERRM 値を戻すことをお勧めします。このようにして、SQLCODE = 0 を確認することで、正常に完了したかどうかを確認できます。提案された変更は、-- addedコメントでマークされています。

CREATE OR REPLACE PROCEDURE TrainInsertByParameter (p_ac2seat   in number,
                                       p_ac3seat  in number,
                                       p_ccseat  in number,
                                       p_sleeperseat  in number,
                                       p_secondseat  in number,
                                       p_date1      in date,
                                       p_trainid   in varchar2,
                                       p_fare in number,
                                       p_fromplace in varchar2,
                                       p_toplace in varchar2,
                                       p_class in varchar2,
                                       p_trainname in varchar2,
                                       p_successCnt  out number,
                                       p_sqlcode out number,    -- added
                                       p_sqlerrm out varchar2)  -- added
IS
  successCnt1 number(6) NOT NULL := 0;
  rowUpdated1 number(6) NOT NULL := 0;
  rowUpdated2 number(6) NOT NULL := 0;
  rowUpdated3 number(6) NOT NULL := 0;  
BEGIN
  SAVEPOINT before;

  INSERT INTO tbltrain
    (ac2seat,ac3seat,acchaircarseat,sleeperseat,secondseat,date1,trainid)
  VALUES
    (p_ac2seat,p_ac3seat,p_ccseat,p_sleeperseat,p_secondseat,p_date1,p_trainid);


  rowUpdated1 := SQL%RowCount;
  successCnt1 := successCnt1 + 1;

  dbms_output.put_line('Successful Insertion tbltrain. count ='||successCnt1);
  dbms_output.put_line('Successful Insertion tbltrain. Row Updated ='||rowUpdated1);

  INSERT INTO tbltraindetail
    (trainid,trainname,from1,to1)
  VALUES
    (p_trainid,p_trainname,p_fromplace,p_toplace);

  rowUpdated2 := SQL%RowCount;
  successCnt1 := successCnt1 + 1;

  dbms_output.put_line('Successful Insertion tbltraindetail. count ='||successCnt1);
  dbms_output.put_line('Successful Insertion tbltraindetail. Row Updated= ' || rowUpdated2);

  INSERT INTO tbltrainfare(trainid,class,fare) VALUES (p_trainid,p_class,p_fare);

  rowUpdated3 := SQL%RowCount;
  successCnt1 := successCnt1 + 1;
  p_successCnt := successCnt1;

  COMMIT;

  dbms_output.put_line('Successful Insertion tbltrainfare. count ='||p_successCnt);
  dbms_output.put_line('Successful Insertion tbltrainfare. Row Updated= '||rowUpdated3);

  p_sqlcode := 0;     -- added
  p_sqlerrm := NULL;  -- added
EXCEPTION
  WHEN Others THEN
    p_sqlcode := SQLCODE;  -- added
    p_sqlerrm := SQLERRM;  -- added

    DBMS_OUTPUT.PUT_LINE('Exception: ' || p_sqlcode || ' ' || SQLERRM);  -- added

    successCnt1 := 0;
    p_successCnt := successCnt1;
    dbms_output.put_line('An error has occured. count ='||p_successCnt);

    ROLLBACK TO before;    
END;

別のシステムから呼び出された PL/SQL プロシージャから SQLCODE と SQLERRM を返す IMO は、エラーが発生したかどうかを判断するための一貫した方法を提供し、エラーの内容を教えてくれるため、良い考えです。YMMV。

共有してお楽しみください。

于 2013-03-31T14:44:47.797 に答える
0

私は自分でそれを行ったことはありませんが、パラメータのサイズを設定する必要があると思います:

// cmd.Parameters.Add("p_successCnt", OracleType.Number).Direction = ParameterDirection.Output;
OracleParameter count = new OracleParameter("p_successCnt", OracleType.Number);
count.Direction = ParameterDirection.Output;
count.Size = 8;
cmd.Parameters.Add(count);

参照: Oracle ストア プロシージャは out パラメータに何も返さない

于 2013-03-31T14:20:46.543 に答える