Dapper.NET을 사용하여 저장 프로 시저 호출에서 Oracle OUT 매개 변수 값 얻기

ado.net c# dapper odac oracle

문제

편집 : Query / QueryMultiple 메서드 대신 Execute 메서드를 사용하여 내 OUT_SUCCESS 매개 변수에 이제 반환 된 값이있는 OracleParameter 가있는 AttachedParam 이 있습니다. 예를 들어 커서가 아닌 매개 변수 검색해야하는 경우이 방법이 유용합니다. 그런 다음 모든 커서가 아닌 출력 매개 변수가있는 프로 시저에 대해 Execute 를 사용하고 커서 출력 매개 변수 로만 프로 시저에 대해 Query / QueryMultiple 을 사용할 수 있습니다. 하지만 커서 매개 변수와 커서가 아닌 출력 매개 변수를 모두 포함 하는 저장 프로 시저를 호출해야하는 경우가 종종 있습니다.

Dapper.NETOracleDynamicParameters 클래스를 사용하여 여러 개의 IN OUT REF CURSOR 성공적으로 반환하고 매핑했지만 단일 OUT 매개 변수 값을 가져올 수 없습니다.

예를 들어, 다음 사양을 사용하여 저장 프로 시저를 호출하려고합니다.

PROCEDURE DO_SOMETHING (
    OUT_SUCCESS    OUT VARCHAR2
)

이를 위해 OracleDynamicParameters , CommandText 등을 가져 오는 메소드가 들어있는 모델을 작성하는 해당 C # 클래스를 작성 했으며 각 매개 변수에 대해 자동 구현 된 특성 포함합니다

public class DO_SOMETHING {
    ... //code to return parameters, etc
    public string OUT_SUCCESS { get; set; }
    ...
}

나는 다음 구문을 모두 시도했다.

using (var gridReader = Connection.QueryMultiple(nModel.CommandText(), param: nModel.DynamicParameters(), commandType: nModel.CommandType()))
{
     OUT_SUCCESS = ((OracleDynamicParameters)Model.DynamicParameters()).Get<string>("OUT_SUCCESS"); // 1
     OUT_SUCCESS = gridReader.Read<string>().Single(); //2
     OUT_SUCCESS = gridReader.Read<DO_SOMETHING>().Single().OUT_SUCCESS; //3
}

그러나 그들 중 누구도 일하지 않습니다 :

  1. AttachedParam 은 이름이 "OUT_SUCCESS" 매개 변수에 대해 null 입니다 (매개 변수가 있음을 알 수 있음)
  2. gridReader 는 "시퀀스에 요소가 없습니다"라는 메시지를 표시합니다. 아마도 응답에서 문자열을 읽는 방법을 모르기 때문입니다.
  3. 이것은 가장 유망한 것 같습니다 - InvalidArgumentException : gridReader 는 "다중 매핑 API를 사용할 때 ID 이외의 키가있는 경우 splitOn 매개 변수를 설정할 수 있도록 보장합니다."그러나 이것이 내 시스템에 어떻게 관련되어 있는지 잘 모르겠습니다. 문제.

ODP.NET이 예외를 생성하지 않고 결과 행이 데이터베이스에 지속되는 것을 볼 수 있기 때문에 프로 시저가 성공적으로 실행되고 있음을 알 수 있습니다.

계속 진행하는 방법을 모르지만, Dapper를 사용하고 싶습니다. 이것이 마지막 남은 장애물입니다. 도움이 항상 감사합니다.

인기 답변

이것은 매우 늦었고 거의 모든 사람에게 공통 지식이 될 수 있지만 너무 오래 전부터 원래 메시지에 주석이 있으므로 커서를 매개 변수로 사용하는 문제에 대해 설명 할 것입니다. 잘 커서가 아닌 매개 변수로.

예제에는 Oracle 커서가 하나만 있기 때문에 Query 메소드를 사용할 수 있습니다. 다른 out 매개 변수의 결과는 매개 변수 자체에 있으며 OracleDynamicParameters 클래스의 Get <> 메소드를 사용하여 검색 할 수 있습니다.

다른 중요한 부분은 out 매개 변수에 크기를 추가하는 것이 었습니다. 그렇지 않으면 null 또는 빈 문자열로 되돌아 왔습니다.

아래는 내가 사용하고있는 코드 샘플입니다.

using (IDbConnection db = new OracleConnection(connectionString)) {
    var p = new OracleDynamicParameters();
    p.Add("p_first_parameter", someParameter, OracleDbType.Varchar2, ParameterDirection.Input);
    p.Add("o_cursr", dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output);
    p.Add("o_sqlerrm", dbType: OracleDbType.Varchar2, direction: ParameterDirection.Output, size: 200);
    p.Add("o_sqlcode", dbType: OracleDbType.Varchar2, direction: ParameterDirection.Output, size: 200);

    dynamic csr = db.Query("myStoredProcedure", p, commandType: CommandType.StoredProcedure).ToList().First();
    string code = p.Get<OracleString>("o_sqlcode").ToString();
    if (code != "0") {
        string errm = p.Get<OracleString>("o_sqlerrm").ToString();
        throw new Exception($"{code} - {errm}");
    }
}


아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.