2015-01-16 2 views
0

SSMS에 지쳐서 내 자신의 SQL 클라이언트를 작성했습니다. SSMS처럼 영향을받은 행 수를 캡처하려고하지만 ExecuteReader이 완료되거나 EndExecuteReader이 호출 될 때 SqlCommand.StatementCompleted가 여러 번 제기됩니다. 일괄 처리의 문이 일정한 간격으로 완료되었지만 DONE_IN_PROC 메시지가 클라이언트에 대기 한 다음 연속적으로 발생시키는 대신 모든 메시지를 한 번에 덤프하는 것처럼 보입니다. 아니요 InfoMessage 이벤트는 실행을 통해 SqlConnection에서 실행됩니다.여러 문장의 레코드 수 검색

위의 업데이트는 이탤릭체입니다.

말은, 그와 같은 SQL의 루프에서 행을 업데이트 문, 또는 뭔가를 :

WHILE 1=1 
BEGIN 
    UPDATE tbl SET .... WHERE Id BETWEEN i AND i+10; 
    IF @@ROWCOUNT =0 BREAK; 
    SET i = i + 10; 
END 

SSMS 제대로 "(영향을받는 10 행)"초 w/E의 모든 X의 수를 표시

. UPDATE 전용 문이므로 판독기에서 오는 레코드가 없으므로 SqlDataReader을 사용하여 행을 계산할 수 없습니다.

SqlClient 라이브러리를 사용하면 가능합니까? 문제

단순화 된 코드는 다음과 같다 : 설명은 덜 명확하지만

class ExecuteWorker 
{ 
    public void Start(string query) 
    { 
    this._query = query; 
    this._thread.Start(this.Work); 
    } 

    void Work() 
    { 
    using(var conn = new SqlConnection(this._connStr)) 
    { 
     conn.Open(); 
     using(var command = conn.CreateCommand()) 
     { 
     command.CommandText = this._query; 
     using(var reader = command.ExecuteReader()) 
     { 
      while(reader.Read()) 
      { 
      this._control.BeginInvoke(new Action(()=>{ 
       // update UI 
      })); 
      } 
     } 
     } 
    } 
    } 
} 

비슷한 질문, here을 찾을 수 있습니다.

+0

SQL 문을 실행하는 데 사용하는 코드는 무엇입니까? – theMayer

+0

@theMayer 빵 & 버터 SqlClient : SqlConnection, SqlCommand, ExecuteReader. –

+0

그것은 할 수 있습니다. 그러나 당신이하는 일에 대해 완전한 구현을보고 싶습니다. – theMayer

답변

0

처리하려는 두 가지 이벤트가 있습니다. SqlConnectionInfoMessageSqlCommandStatementCompleted.

죄송합니다. VB 코드는 사용하실 수 있지만 변환 할 수 있어야합니다.

Private Sub OnInfoMessage(sender As Object, args As SqlClient.SqlInfoMessageEventArgs) 
    For Each sqlEvent As System.Data.SqlClient.SqlError In args.Errors 
     Dim msg As String = String.Format("Msg {0}, Level {1}, State {2}, Line {3}{4}", sqlEvent.Number, sqlEvent.Class, sqlEvent.State, sqlEvent.LineNumber, Environment.NewLine) 
     'Write msg to output 
    Next 
End Sub 

Private Sub OnStatementCompleted(sender As Object, args As StatementCompletedEventArgs) 
    Dim msg As String = String.Format("({0} row(s) affected)", args.RecordCount) 
    'Write msg to output 
End Sub 

Public Sub Work() 
    Using dbc As New SqlConnection(Me.ConnectionString), 
      dbcmd As New SqlCommand() 

     dbcmd.Connection = dbc 
     dbcmd.CommandTimeout = Convert.ToInt32(timeout) ' you will want to set this otherwise it will timeout after 30 seconds 
     'set other dbcmd properties 

     AddHandler dbc.InfoMessage, New SqlInfoMessageEventHandler(AddressOf OnInfoMessage) 
     AddHandler dbcmd.StatementCompleted, AddressOf OnStatementCompleted 

     dbc.Open() 

     'dbcmd.ExecuteNonQuery() or Using dataReader As SqlDataReader = dbcmd.ExecuteReader() 

    End Using 
End Sub 
+0

업데이트 된 질문을 참조하십시오. 'StatementCompleted'는 각 문장에 대해 발생하지만'ExecuteReader'가 끝날 때만 발생합니다. 기본적으로 한 번에 수많은 StatementCompleted 이벤트가 발생합니다. 한편, 배치가 실행되고 성공적으로 실행되는지 여부는 알 수 없습니다. –

+0

@ mr-ta 내 코드는 모든 스트림이 같은 스트림에 쓰고있는 asp.net 응용 프로그램에서이며 올바른 순서로 메시지를 생성합니다. 비동기/대기를 사용해야 할 수도 있습니다. 그러나 익숙하지는 않습니다. – Nicholas

+0

@ mr-ta 한 가지 다른 점은 SQL 코드에서 print 또는 raiserror를 사용하고 있습니까? 결과 세트 나 배치가 반환 될 때까지 인쇄가 지연된다고 생각합니다. raiserror ('msg', 0, 0)를 사용해보십시오. 귀하의 SQL 코드에서 어떻게되는지보십시오. – Nicholas

0

왜 SQL을 저장 프로 시저로 옮기지 않습니까? 출력 매개 변수를 포함하는 매개 변수 컬렉션이있는 명령 개체를 사용하여 저장 프로 시저를 실행합니다. 저장 프로 시저 내에서 영향을받는 개별 업데이트 행을 합계하는 총 개수 변수가 있습니다. 이것을 출력 매개 변수로 리턴하십시오.

+0

귀하의 제안은 내가 만족시키려는 요구 사항을 잘못 찾습니다. SSMS처럼 작업을 작성한 SQL 클라이언트를 만들려고합니다. 다중 행 배치가 실행될 때 영향을받는 행 수를보고하십시오. 분명히 SQL을 조정하여 비슷한 작업을 수행 할 수는 있지만 SQL 클라이언트가 필요하다는 점에서 패배합니다. –

0

ExecuteNonQuery 메서드를 사용하여 db를 업데이트하면 영향을받는 행 수를 반환합니다. 이 메서드는 insert, update 또는 delete sql 명령을 사용할 때 사용됩니다. 희망이 당신이 찾고있는 것입니다.

+0

그건 작동하지 않습니다. 이 메서드는 레코드 수를 하나만 반환합니다. 일괄 처리의 여러 명령문에서 0 이상의 개수를 캡처해야합니다. 내 질문을 다시 읽으십시오. 가장 빈번한 시나리오 중 하나는 루프로 분할 된 매우 긴 작업입니다. 루프를 포함하는 SQL 배치를 여러 ExecuteNonQuery 호출로 분할하는 방법은 없습니다. –

+0

[이 링크] (http://stackoverflow.com/questions/1880471/capture-stored-procedure-print-output-in-net)에 제시된 답변을 시도해 보셨습니까? – Bhaskar

+0

업데이트 된 질문보기 –

관련 문제