2012-08-10 33 views
5

SQL Server Management Studioから対話形式でSQLコマンドを実行するユーザーに表示されるsqlコマンドの出力は、ADOコマンドまたはADOクエリオブジェクトの実行から戻される出力とは異なります。SQL BACKUPコマンドの結果出力をDelphiプログラムに取り込むにはどうすればよいですか?

USE [DBNAME] 
BACKUP DATABASE [DBNAME] TO 
DISK = 'C:\SqlBackup\Backup.mdf' 

正常に完了出力は、このようなものです:

私は上記のように設定するのCommandTextまたはSQLでTADOCommandはやTADOQueryのいずれかを実行し
Processed 465200 pages for database 'DBNAME', file 'filename' on file 2. 
Processed 2 pages for database 'DBNAME', file 'filename_log' on file 2. 
BACKUP DATABASE successfully processed 465202 pages in 90.595 seconds (40.116 MB/sec). 

が、私はそのような出力を得ることはありません。 SQLコマンドの実行からこの「副出力」をどのように読み取るのですか?私はおそらく、いくつかの生のADO操作を介して、私はコマンドを実行し、成功のために上記の情報を得ることができると期待しているだけでなく、SQLバックアップを実行する際のエラー。

更新:答えは以下の平野デルファイTADOCommandはとTADOConnectionのクラスを使用して、動作しませんでした私の素朴な試み、より私のために良い作品:

  • TADOCommandはとTADOConnectionのを作成します。
  • 実行コマンド。
  • get info-messages back。

私自身のコーディング試行で経験した問題は、私の最初のコマンドは "use dbname"で、私のコードで辿った唯一のレコードセットは、 "use dbname"コマンドの結果で、2番目私が実行していたコマンド。以下の回答は、ADOコマンドの実行から戻ってくるすべてのレコードセットをトラバースします。私はバックグラウンドスレッドでこれをやっているので、実際には生のCom Objectsを作成して、スレッドでVCLエンタングルメントを避けるほうが良いと思います。誰かが興味を持っていれば、以下のコードは素晴らしいコンポーネントになるかもしれません、私に知らせてください。オープンソースの "SQL Backup for Delphi"コンポーネントを作るかもしれません。

+1

おそらく関連していますか? http://stackoverflow.com/questions/254486/view-output-of-print-statements-using-adoconnection-in-delphi?rq=1 –

+0

返信を受け取る前に、ADOQueryまたはADOCommandがタイムアウトしている可能性がありますかデータベースから? CommandTimeOutのデフォルト値は30です。 –

+0

SQLサーバーからこのメッセージを処理するTADOConnection.OnInfoMessageハンドラを定義します。 – valex

答えて

5

ここは例です。私はD7とMSSQL2000でそれをテストしました。そして、それは、サーバからのすべてのメッセージをMEMO1する追加:

29 percent backed up. 
58 percent backed up. 
82 percent backed up. 
98 percent backed up. 
Processed 408 pages for database 'NorthWind', file 'Northwind' on file 1. 
100 percent backed up. 
Processed 1 pages for database 'NorthWind', file 'Northwind_log' on file 1. 
BACKUP DATABASE successfully processed 409 pages in 0.124 seconds (26.962 MB/sec). 

それは長い時間がかかる場合もありませんメインスレッドでWHILEループを実装することを検討してください。

uses AdoInt,ComObj; 
..... 

procedure TForm1.Button1Click(Sender: TObject); 
var cmd : _Command; 
    Conn : _Connection; 
    RA : OleVariant; 
    rs :_RecordSet; 
    n : Integer; 
begin 
    Memo1.Clear; 

    Conn := CreateComObject(CLASS_Connection) as _Connection; 
    Conn.ConnectionString := 'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=NorthWind;Data Source=SQL_Server'; 
    Conn.Open(Conn.ConnectionString,'','',Integer(adConnectUnspecified)); 

    cmd := CreateComObject(CLASS_Command) as _Command; 
    cmd.CommandType := adCmdText; 
    cmd.Set_ActiveConnection(Conn); 
    cmd.CommandText := 'BACKUP DATABASE [NorthWind] TO DISK = N''c:\sql_backup\NorthWind'' WITH INIT , NOUNLOAD , NAME = N''NortWind backup'', NOSKIP , STATS = 10, NOFORMAT;'; 
    rs:=cmd.Execute(RA,0,Integer(adCmdText)); 

    while (rs<>nil) do 
    begin 
    for n:=0 to(Conn.Errors.Count-1)do begin 
    Memo1.Lines.Add(Conn.Errors.Item[n].Description); 
    end; 
    rs:=rs.NextRecordset(RA); 
    end; 

    cmd.Set_ActiveConnection(nil); 
    Conn.Close; 
    cmd := nil; 
    Conn := nil; 
end; 

私は、ストアドプロシージャのthis thread (Russian)を発見し、BACKUPコマンドのためにそれを修正しました。

+0

上記のコードは、ネイティブのDelphiラッパーが上記のRAで渡された設計意図を破らずに 'rs:= NextRecordSet(RA)'に戻った場合、ネイティブのDelphiオブジェクトで動作します。 –

+4

私は上記のDelphi 2007とXE2をMS SQL Server 2008 R2とSQL Server 2012でテストしましたが、そこでも動作します。私はそれをバックグラウンドスレッドに移しました。なぜなら、それはいつも私の計画だったからです。誰かが上記のオープンソースコンポーネントのバージョン(スレッド)を望むなら、私に知らせてください(アップヴォートはコメントよりもスペースが少なくて済みます)。 –

+1

コンポーネントがあるときはここにリンクを投稿します。 –

関連する問題