programing

C#에서 참조 커서를 반환하는 Oracle Function 실행

sourcejob 2023. 9. 26. 22:19
반응형

C#에서 참조 커서를 반환하는 Oracle Function 실행

아웃 레퍼런스 커서가 있는 프로시저가 있는 오라클 패키지가 있습니다.제가 알기로는 이것은 꽤 표준적인 것입니다.

제가 싫어하는 것은 결과물을 보기 위해서 수많은 코드를 써야 한다는 사실입니다.그래서질문을 해봤는데 절차를 포장하는 기능을 만들어서 원하는 것을 얻을 수 있다고 합니다.

업데이트: 더 이상 기능이 필요 없어 보이지만 궁금하신 분들은 원래 질문과 답변 업데이트를 보실 수 있습니다.

여기 기능이 있습니다.

FUNCTION GetQuestionsForPrint (user in varchar2)
  RETURN MYPACKAGE.refcur_question
AS  

    OUTPUT MYPACKAGE.refcur_question;

BEGIN 

      MYPACKAGE.GETQUESTIONS(p_OUTPUT => OUTPUT, 
      p_USER=> USER ) ;


  RETURN OUTPUT;
END;

SQL 개발자에서 이를 실행하기 위해 수행하는 작업은 다음과 같습니다.

var r refcursor;
exec :r := mypackage.getquestionsForPrint('OMG Ponies');
print r;

이제부터는 모든 절차에 ForPrint 기능을 추가할 예정입니다.

이것 때문에 저는 어쩌면 기능이 제가 원하는 것이고 절차가 필요하지 않다는 생각을 하게 되었습니다.

이를 테스트하기 위해 에서 함수를 실행하려고 했습니다.NET, 내가 할 수 없는 것 빼고는.이게 정말로 그런 건가요.

using (OracleConnection cnn = new OracleConnection("Data Source=Test;User Id=Test;Password=Test;"))
{
    cnn.Open();
    OracleCommand cmd = new OracleCommand("mypackage.getquestionsForPrint");
    cmd.CommandType = System.Data.CommandType.StoredProcedure;

    cmd.Parameters.Add ( "p_USER", "OMG Ponies");

    cmd.Connection = cnn;
    OracleDataReader rdr = cmd.ExecuteReader();

    while (rdr.Read())
    {
        Console.WriteLine(rdr.GetOracleValue(0));
    }

    Console.ReadLine();
}

그래서 저는 오류가 납니다.

getquestionsForPrint is not a procedure or is undefined

동일한 결과로 ExecuteScalar도 시도해 보았습니다.

편집 Slider345의 조언을 받아들이다 명령 유형을 텍스트로 설정하고 다음 문장을 사용하려고 시도했는데 유효하지 않은 SQL 문장이 나타납니다.

mypackage.getquestionsForPrint('OMG Poinies');

그리고.

var r refcursor; exec :r :=  mypackage.getquestionsForPrint('OMG Poinies'); 

명령 텍스트에 Abhi의 변형 사용

select mypackage.getquestionsForPrint('OMG Poinies') from dual

결과적으로

"0x61c4aca5"의 명령은 "0x00000ce1"의 메모리를 참조했습니다.메모리를 "읽기"할 수 없습니다.

제가 잘못 알고 있는 건가요?

업데이트 출력 매개 변수를 추가하려고 해도 도움이 되지 않습니다.

cmd.Parameters.Add(null, OracleDbType.RefCursor, ParameterDirection.Output);

함수의 반환 값이기 때문에 이름이 무엇인지 확실하지 않지만(null, 빈 문자열, mypackage.get questionsForPrint를 시도했습니다) 모든 경우에 결과가 나타납니다.

ORA-06550: 1번 행, 7번 열: PLS-00306: 'get questionsForPrint'에 호출된 인수 또는 유형이 잘못되었습니다.

최종 편집(희망사항)

Guddie가 3개월 후에 비슷한 질문을 한 것 같습니다.그는 하기 위한 답을 얻었습니다.

  • 명령 텍스트를 익명 블록으로 설정
  • 출력할 방향을 설정하는 리플렉터에 파라미터 바인딩
  • 판독기가 아닌 실행을 호출합니다.
  • 그런 다음 매개 변수를 사용합니다.

using (OracleConnection cnn = new OracleConnection("Data Source=Test;User Id=Test;Password=Test;"))
{
    cnn.Open();
    OracleCommand cmd = new OracleCommand("mypackage.getquestionsForPrint");
    cmd.CommandType = CommandType.Text;

    cmd.CommandText = "begin " +
              "    :refcursor1 := mypackage.getquestionsForPrint('OMG Ponies') ;"  +
              "end;";

    cmd.Connection = cnn;
    OracleDataAdapter da = new OracleDataAdapter(cmd);
    cmd.ExecuteNonQuery();

    Oracle.DataAccess.Types.OracleRefCursor t = (Oracle.DataAccess.Types.OracleRefCursor)cmd.Parameters[0].Value;
    OracleDataReader rdr = t.GetDataReader();
    while(rdr.Read())
        Console.WriteLine(rdr.GetOracleValue(0));

    Console.ReadLine();
}

저는 이것을 함수로 테스트한 것이 아니라 저장된 절차로 테스트한 것입니다.refCursor의 out 파라미터를 지정합니다.

command.Parameters.Add(new OracleParameter("refcur_questions", OracleDbType.RefCursor, ParameterDirection.Output));

CommandType으로 기능을 작동시킬 수 있는 경우.문자. 다음과 같은 방향을 제외하고 위의 파라미터를 추가해 볼 수 있는지 궁금합니다.

ParameterDirection.ReturnValue

저는 오라클을 사용하고 있습니다.Data Access 버전 2.111.6.0

문제와 답 사이를 오가며 전체 코드를 알아내야 했습니다.그래서 다른 사람들을 위해 내게 도움이 된 모든 코드를 여기에 제공합니다.

var sql = @"BEGIN :refcursor1 := mypackage.myfunction(:param1) ; end;";
using(OracleConnection con = new OracleConnection("<connection string>"))
using(OracleCommand com = new OracleCommand())
{
     com.Connection = con;
     con.Open();
     com.Parameters.Add(":refcursor1", OracleDbType.RefCursor, ParameterDirection.Output);
     com.Parameters.Add(":param1", "param");
     com.CommandText = sql;
     com.CommandType = CommandType.Text;
     com.ExecuteNonQuery();
     OracleRefCursor curr = (OracleRefCursor)com.Parameters[0].Value;
     using(OracleDataReader dr = curr.GetDataReader())
     {
         if(dr.Read())
         {
             var value1 = dr.GetString(0);
             var value2 = dr.GetString(1);
         }
     }
 }

도움이 되길 바랍니다.

나는 이것이 꽤 오래된 게시물이라는 것을 알고 있지만, 내가 얻는 데에 관련된 모든 사소한 것들을 알아내는 데 너무 오래 걸렸기 때문입니다.NET은 Oracle과 함께 "멋진 싸움"을 하기 위해 이 어려운 상황에 처한 다른 사람들을 위해 이 조언을 제공할 것이라고 생각했습니다.

환경에서 REF_CURRS를 반환하는 Oracle 저장 프로시저(.)를 자주 호출합니다.오라클 대비 NET 3.5 11g).함수의 경우, 매개 변수 이름을 원하는 대로 지정할 수 있지만, 그 다음에는 매개 변수를 설정해야 합니다.System.Data.ParameterDirection=ParameterDirection.ReturnValue그리고나서ExecuteNonQuery을 상대로OracleCommand물건.이때 해당 매개 변수의 값은 Oracle 함수가 반환한 ref_cursor가 됩니다.그 가치를 그저 다음과 같이 생각해주세요.OracleDataReader그리고 순환을 합니다.OracleDataReader.

전체 코드를 게시하고 싶지만 데이터 액세스 계층을 VB로 작성했습니다.수년 전의 NET에서는 데이터 액세스 계층(회사 인트라넷)을 소비하는 코드의 대부분이 C#에 있습니다.한 번의 응답으로 언어를 섞는 것이 더 큰 가짜 패스가 될 것이라고 생각했습니다.

언급URL : https://stackoverflow.com/questions/3535405/execute-an-oracle-function-that-returns-a-reference-cursor-in-c-sharp

반응형