Pertanyaan Dari Stored Procedure, return OUT parameter & OUT cursor & hasil parse (Oracle)


Pertanyaan: Apakah mungkin untuk kembali menggunakan OUT:

Kedua: A & A variabel kursor, dari kode saya di bawah ini ??


Saya melihat pertanyaan serupa untuk SqlDB tetapi setelah pencarian yang sangat lama tidak menemukan solusi untuk OracleDB.

Di PLSQL:

CREATE OR REPLACE
PROCEDURE SPGETRESULTANDSETFLAG
(
 pFilter VARCHAR2,
 pMaxRowCount VARCHAR2,
 pTableID RAW,
 myFlag OUT NUMBER,
 myCursor OUT types.cursorType
)
AS
BEGIN
 Declare
  CountQuery VARCHAR(20000) := '';
  DataQuery VARCHAR(20000) := '';
  ResultingRows NUMBER := -1;
 Begin
  myFlag := -1;

  CountQuery := 'SELECT COUNT(*) FROM ' 
                || F_GET_TABLENAME_FROM_ID(PTABLEID => pTableID)
                || ' WHERE ' || pFilter;
  EXECUTE IMMEDIATE CountQuery INTO ResultingRows;


  --Get the Return Value
  if( pMaxRowCount > ResultingRows ) then myFlag := 1; end if;


  DataQuery := 'SELECT * FROM '
                || F_GET_TABLENAME_FROM_ID(PTABLEID => pTableID) 
                || ' WHERE ' || pFilter; 
  --Get the Return Cursor
  Open myCursor for DataQuery;

 End;
END SPGETRESULTANDSETFLAG;

Di Code Behind ..

Database db = DBSingleton.GetInstance();
using (DbCommand command = db.GetStoredProcCommand(spName))
{
    //The three Add In Parameters... & then the Add out Parameter as below
    db.AddOutParameter(command, "myFlag", System.Data.DbType.Int32, LocVariable );
    using ( IDataReader reader = db.ExecuteReader(command))
    {
         //Loop through cursor values & store them in code behind class-obj(s)
    }
}

Saya pikir ini tidak mungkin karena bagaimana saya membaca nilai & kursor, karena ..

kalau saja flag param keluar kalau begitu saya akan menggunakan db.ExecuteNonQuery (..) & jika hanya kursor keluar kemudian saya akan menggunakan db.ExecuteReader (..)


5
2017-07-30 10:57


asal


Jawaban:


Ya, dimungkinkan untuk memiliki lebih dari satu parameter. Berikut ini contoh yang saya gunakan untuk memanggil prosedur tersimpan Oracle di c #:

OracleParameter op = null;
OracleDataReader dr = null;

/* custom code here. Yours would look a little different */
OracleCommand cmd = (OracleCommand) this.FactoryCache.Connection.CreateCommand();

cmd.CommandText = "pkg_prov_index.getNextPanel";
cmd.CommandType = CommandType.StoredProcedure;

op = new OracleParameter("pCurrentPanelId", OracleType.VarChar);
op.Direction = ParameterDirection.Input;
op.Value = masterProviderIndex.CurrentPanelId;
cmd.Parameters.Add(op);

op = new OracleParameter("pRefCursor", OracleType.Cursor);
op.Direction = ParameterDirection.Output;
cmd.Parameters.Add(op);

op = new OracleParameter("pReturnCode", OracleType.Number);
op.Direction = ParameterDirection.Output;
op.Size = 5;
cmd.Parameters.Add(op);

op = new OracleParameter("pReturnMessage", OracleType.VarChar);
op.Direction = ParameterDirection.Output;
op.Size = 4000;
cmd.Parameters.Add(op);

cmd.ExecuteNonQuery();

returnCode = Convert.ToInt16(cmd.Parameters[2].Value);
returnMessage = cmd.Parameters[3].Value.ToString();

dr = (OracleDataReader) cmd.Parameters[1].Value;

while (dr.Read()) {
}

7
2017-07-30 13:22



Terima kasih atas jawabannya

Saya benar-benar putus asa untuk mendapatkan hasil kerja & entah bagaimana menemukan solusi & setelah membaca sedikit mengetahui mengapa itu berhasil:


Oracle Stored Procedure tidak ada perubahan.


Kode Dibalik - Berubah sebagai berikut:

Database db = DBSingleton.GetInstance();
using (DbCommand command = db.GetStoredProcCommand(spName))
{
    //The three Add In Parameters... & then the Add out Parameter as below
    db.AddOutParameter(command, "myFlag", System.Data.DbType.Int32, LocVariable );
    using ( IDataReader reader = db.ExecuteReader(command))
    {
         //Loop through cursor values & store them in code behind class-obj(s)
         //The reader must be closed before trying to get the "OUT parameter"
         reader.Close();

         //Only after reader is closed will any parameter result be assigned
         //So now we can get the parameter value.
         //if reader was not closed then OUT parameter value will remain null
         //Getting the parameter must be done within this code block
         //I could not get it to work outside this code block
         <Type> result = (typecast)command.Parameters["OUT_parameter_name"];
    }
}
//I USED THIS APPROACH TO RETURN MULTIPLE PARAMETERS ALONG WITH THE CURSOR READ

3
2017-08-01 19:49



            using (myCmd)
            {
                myCmd.Parameters.AddWithValue("p_session_id", sessionId);
                myCmd.Parameters.AddWithValue("p_user", SessionHelper.UserEmailID);

                OracleParameter retval = new OracleParameter("p_status", OracleType.NVarChar, 35);
                retval.Direction = ParameterDirection.Output;
                myCmd.Parameters.Add(retval);


                OracleParameter retval2 = new OracleParameter("p_status_dtl", OracleType.NVarChar, 300);
                retval2.Direction = ParameterDirection.Output;
                myCmd.Parameters.Add(retval2);

                OracleParameter retval3 = new OracleParameter("p_output", OracleType.Cursor);
                retval3.Direction = ParameterDirection.Output;
                myCmd.Parameters.Add(retval3);
                myCmd.ExecuteNonQuery();
                status = myCmd.Parameters["p_status"].Value.ToString();
                statusDetail = myCmd.Parameters["p_status_dtl"].Value.ToString();

                using (OracleDataReader reader = (OracleDataReader)myCmd.Parameters["p_output"].Value)
                {
                    outPutDt.Load(reader);
                }
            }

}


1
2017-07-28 06:18



Saya tidak tahu perpustakaan mana yang Anda gunakan untuk akses Oracle ... tetapi biasanya dimungkinkan untuk mendeklarasikan kursor keluar dan param keluar sebagai Parameter dan menggunakan ExecuteNonQuery dengan blok PL / SQL anoynmous (di mana Anda memanggil Stored Prosedur) ... misalnya dengan komponen Devcart dotconnect, ini mungkin ... (tidak direferensikan, hanya pelanggan yang senang)


0
2017-07-30 11:27



Seseorang dapat mempertimbangkan alternatif untuk kueri berulang dalam prosedur Anda. Sebagai contoh:

CREATE OR REPLACE
PROCEDURE SPGETRESULTANDSETFLAG
(
 pFilter VARCHAR2,
 pTableID RAW,
 myCursor OUT types.cursorType
)
AS
  DataQuery VARCHAR(20000) := '';
BEGIN
  DataQuery := 'SELECT COUNT(*) OVER () AS TheCount, T.* FROM '
                || F_GET_TABLENAME_FROM_ID(PTABLEID => pTableID) 
                || ' AS T WHERE ' || pFilter; 
  --Get the Return Cursor
  Open myCursor for DataQuery;

END SPGETRESULTANDSETFLAG;

Dengan cara ini Anda tidak perlu query tabel dua kali, Anda memiliki hitungan di setiap baris dari resultset Anda. Anda dapat menyingkirkan parameter Anda yang berhubungan dengan max rowcount juga, dan periksa nilai hitungan dalam rutin panggilan Anda dengan mengambil satu baris.

Hanya pemikiran alternatif ...


-1
2017-07-30 21:50