2013-02-22 2 views
1

기존 응용 프로그램을 Sybase에서 SQL Server 2008로 변환하려고합니다. 응용 프로그램은 ODBC를 사용하여 데이터베이스에 연결합니다. 간단히 연결 문자열을 변경하는 것은 대부분의 앱 기능에 적용되었지만 나를 혼란스럽게 만드는 버그가 하나 있습니다. 나는 버그를 보여주는 간단한 예제를 만들었다.ODBC를 사용하여 SQL Server 결과 집합을 반환하는 중 오류가 발생했습니다.

내가 저장 프로 시저가 : 저장 프로 시저를 실행하고로 결과를로드

create procedure dbo.test_sel 
as 
begin 
    create table #cfg 
    (
    Name varchar(100) NULL, 
    Dscr varchar(50) NULL 
) 

    insert #cfg(Name, Dscr) 
    values('Config', 'Config description') 

    select COUNT(*) as [Count] from #cfg 

    return 0 
end 

코드를 DataTable을 : 나는 메시지가 값을 보여 기대

{ 
    OdbcCommand cmd = new OdbcCommand("test_sel", new OdbcConnection("Driver={SQL Server};Server=xxx;Database=xxx;Uid=xxx;Pwd=xxx")); 

    DataTable dt = new DataTable(); 

    OdbcDataAdapter da = new OdbcDataAdapter(cmd); 

    using (cmd.Connection) 
    { 
     da.Fill(dt); 
    } 

    MessageBox.Show(dt.Rows.Count.ToString()); 
} 

1 단일 행을 포함하는 DataTable. 그러나 DataTable은 비어 있습니다 (결과 집합이 반환되지 않음). 내가 저장 프로 시저에 insert 문을 주석으로 다음 코드를 다시 실행하면

지금, 나는 시도 0

의 값을 하나의 행, 하나의 열 이름 수를 포함 반환 된 결과 집합을받을 수 있나요 예를 들어 임시 테이블보다는 영구 테이블을 사용하는 스토어드 프로 시저의 많은 변형이 있습니다.하지만 같은 일이 발생할 때마다 - 삽입으로 인해 저장 프로 시저가 결과 세트를 반환하지 않게됩니다.

ODBC 드라이버를 SQL Server 2008로 변경해도 아무런 차이가 없습니다. 이 코드는 Sybase를 사용할 때와 MS SQL Server Management Studio에서 실행할 때 예상대로 작동합니다.

는 구글 검색 후 나는 다음과 같은 코드를 시도 :

{ 
    SqlCommand cmd = new SqlCommand("test_sel", new SqlConnection("Server=xxx,5100;Database=xxx;User ID=xxx;Password=xxx")); 

    DataTable dt = new DataTable(); 

    SqlDataAdapter da = new SqlDataAdapter(cmd); 

    using (cmd.Connection) 
    { 
     da.Fill(dt); 
    } 

    MessageBox.Show(dt.Rows.Count.ToString()); 
} 

지금이 작품을하지만, 응용 프로그램이 두 데이터베이스에서 작동해야하기 때문에 나는 그것을 도울 수 있다면 차라리 이것에 대한 코드를 변경하지 않을 것입니다.

아무도 왜 원래 코드가 작동하지 않는지 제안 할 수 있습니까? 정말 단순한 것만 큼 괜찮은 것처럼 보입니다.

답변

0

(동일하게 작동합니다 모두 OdbcDataAdapterSqlDataAdapter에 대한 Fill 때문에이 버그처럼 보인다 나에게) 당신이이 일을하는 데 사용할 수있는 두 가지 옵션이 있습니다 :

1) 절차의 시작 부분에서 begin 키워드 후에는

set nocount on 

2)보다는 DataTable 걸리는 하나를 매개 변수로 DataSet 소요 Fill 메서드의 오버로드를 사용하여 추가 할 수 있습니다.

MSDN 상태 : DataTable을 매개 변수로 사용하는 Fill의 오버로드는 첫 번째 결과 인 만 가져옵니다.

INSERT이 실행되고 NOCOUNT이 꺼져 있으면 명령문의 영향을받은 행 수에 대한 정보가 반환됩니다. 따라서이 옵션을 해제하면 행 수는 2 회보고됩니다 (SSMS의 '메시지'창에서 확인할 수 있음). 한 번만 INSERT로, 두 번째로 SELECT를 선택합니다. 첫 번째 행 수 (INSERT에서)가 어떻게 든 첫 번째 결과 집합으로 해석되는 것 같습니다.이 행 수는 INSERT 문이 아니며 SELECT이 아니므로 반환 할 행이 없습니다.

+0

많은 감사합니다. 고정 된 세트에 nocount가 있습니다. –

+0

당신은 환영합니다 :) –

+0

그냥 ODBC의 관점에서 Ivan G의 답변을 추가 할 수 있습니다. ODBC 용어에서 nocount가 off이면 프로 시저의 각 insert/update/delete/select는 별도의 결과 집합으로 간주됩니다. ODBC 용어에서는 SQLMoreResults를 호출하여 영향을받는 행 수를 찾을 수 있도록 이러한 결과 세트를 이동합니다. – bohica

관련 문제