2016-07-25 1 views
0

오라클 스토어드 프로 시저를 C#에서 호출 한 적이 처음이며 코드가 작동하지 않는 이유를 알 수 없습니다. 내가하려는 것은 datatable을 반환하는 것뿐입니다. 내 저장 프로 시저가 잘 컴파일 - 여기하는 일부 의사는 그것을 설명한다 : 여기 C#에서 Oracle 스토어드 프로 시저 호출 문제

CREATE OR REPLACE PROCEDURE SPROC_ONLINE 
(Year IN NUMBER DEFAULT NULL 
, Name IN VARCHAR2 DEFAULT NULL 
, ID IN VARCHAR2 DEFAULT NULL 
, refCursor OUT SYS_REFCURSOR 
) 
AS 
BEGIN 
OPEN refCursor FOR 
SELECT * 
FROM TABLE 
WHERE Field_Year = Year 
    AND Field_Name = Name 
    AND Field_ID = ID; 
END SPROC_ONLINE; 

내 C#을 설명하는 몇 가지 의사 코드입니다 :

public static DataTable search(int? Year, string Name, string ID) 
    {    
     try 
     { 
      OracleConnection conn = getConnectionString();     
      OracleCommand cmd = new OracleCommand(); 
      cmd.Connection = conn; 
      cmd.CommandText = "SPROC_ONLINE"; 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Parameters.Add("Year", OracleDbType.Int32).Value = Year; 
      cmd.Parameters.Add("Name", OracleDbType.Varchar2).Value = Name; 
      cmd.Parameters.Add("ID", OracleDbType.Varchar2).Value = ID;     
      cmd.Parameters.Add("Output", OracleDbType.RefCursor).Direction = ParameterDirection.Output; 

      DataTable dt = new DataTable(); 
      OracleDataAdapter da = new OracleDataAdapter(cmd); 
      getConnectionString().Open(); 
      cmd.ExecuteNonQuery(); 
      da.Fill(dt); 

      return dt;     
     } 
     catch (Exception e) { throw new Exception("Error: " + e.Message); } 
     finally { getConnectionString().Close(); } 
    } 

오류가 발생하지되고있다을; 그것은 단지 반환되어야하는 datatable이 null이 아닐 때입니다 (테스트하는 매개 변수가 뭔가를 반환해야 함).

내가 뭘 잘못하고 있니?

+2

ExecuteNonQuery에는 의미가 없습니다. 그것을 제거하십시오 – Steve

+1

사이드 노트 : 어떤 구현이'getConnectionString(). Close()'내부에 있는지 모르겠습니다 만, 그게 나쁜 습관이 될 정적 연결을 반환한다면. 일반적으로 새로운 (공유되지 않는) 데이터베이스 연결 객체가 필요할 때 생성하고 완료되면 해당 객체를 처리하려고합니다. 그렇지 않으면 나중에 데이터베이스와 개별적으로 무언가를하는 스레드가 두 개 이상있는 경우 나중에 문제가 발생합니다. 데이터베이스 구현이 연결 풀링에 대해 걱정할 수있게하십시오. * 오라클이 많은 문제없이이 문제를 처리 할 수 ​​있다고 생각합니다. – Igor

+0

@Igor - 제안 해 주셔서 감사합니다. 귀하의 의견은 제가 몇 가지 추가적인 연구를하게 만들었습니다. 지금까지는 작은 응용 프로그램에서만 작업 해 왔지만이 사실을 알지 못했습니다. 고맙습니다. – Jake

답변

0

내 문제는 두 가지로 끝났습니다. 여기에 내가 함께 종료 코드 숨김은 다음과 같습니다

public static DataTable search(int? Year, string Name, string ID) 
{ 
    try 
    { 
     using (var cmd = new OracleCommand("SPROC_ONLINE", getConnectionString())) 
     { 
      cmd.CommandType = CommandType.StoredProcedure; 
      var da = new OracleDataAdapter(cmd); 
      cmd.Parameters.Add("Year", OracleDbType.Int32).Value = Year; 
      cmd.Parameters.Add("Name", OracleDbType.Varchar2).Value = Name; 
      cmd.Parameters.Add("ID", OracleDbType.Varchar2).Value = ID; 
      cmd.Parameters.Add("Output", OracleDbType.RefCursor).Direction = ParameterDirection.Output; 
      DataTable dt = new DataTable(); 
      da.Fill(dt); 
      return dt; 
     } 
    } 
    catch (Exception e) {throw new Exception("Error: " + e); } 
    finally {} 
} 

내 다른 문제는 제가 오라클에서 해당 문자열 비교는 대소 문자를 구분했다 몰랐어요이었다. 분명히 SQL Developer에서 저장 프로 시저를 컴파일하고 Visual Studio에서 테스트하기 위해 필자는 "Name"매개 변수를 일관되게 입력하지 않았습니다. 이것은 null 데이터 테이블이 반환되는 이유를 설명합니다. 내 저장 프로 시저의 WHERE 절을 다음과 같이 조정했습니다.

WHERE Field_Year = Year 
    AND UPPER(Field_Name) = UPPER(Name) 
    AND Field_ID = ID; 

모든 것이 올바르게 작동합니다.

1

OracleDataReader을 사용해야 할 수도 있습니다.

+0

이 경우 동적으로 while 루프 내부에 내 datatable을 만들어야합니까? – Jake

+0

@Jake : 맞습니다. – Ingenioushax

관련 문제