2012-08-10 24 views
5

La salida de los comandos sql que es visible para los usuarios que ejecutan comandos SQL de forma interactiva desde el estudio de SQL Server Management es diferente a la salida que obtiene al ejecutar un comando ADO u objeto de consulta ADO.¿Cómo obtengo el resultado de un comando SQL BACKUP en un programa Delphi?

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

El éxito de salida conclusión es la siguiente:

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). 

Cuando ejecuto bien un TADOCommand o TADOQuery con CommandText o SQL establecer que el anterior, que no reciben dicha salida. ¿Cómo leo esta "salida secundaria" de la ejecución de un comando SQL? Espero que, tal vez, a través de algunas operaciones sin procesar de ADO, pueda ejecutar un comando y recuperar la información anterior, para tener éxito, así como cualquier error al realizar una copia de seguridad Sql.

actualización: La respuesta de abajo funciona mejor para mí que mi ingenuo intento, que no funcionaba, el uso de civil clases Delphi TADOCommand y TADOConnection:

  • crear TADOCommand y TADOConnection.
  • ejecute el comando.
  • recuperar mensajes de información.

El problema que he visto en mis propios intentos de codificación, es que mi primera orden es "uso nombredb" y el único conjunto de registros recorrí en mi código, era el resultado de la "utilización nombredb" de comandos, no el segundo comando que estaba ejecutando. La respuesta aceptada a continuación atraviesa todos los conjuntos de registros que regresan de ejecutar el comando ADO, y por lo tanto funciona mucho mejor. Dado que estoy haciendo todo esto en un hilo de fondo, en realidad creo que es mejor crear los Com Objects crudos de todos modos, y evitar cualquier enredo de VCL en mi hilo. El siguiente código podría ser un buen componente si alguien está interesado, hágamelo saber y podría crear un componente de código abierto "SQL Backup for Delphi".

+1

Posiblemente relacionado? http://stackoverflow.com/questions/254486/view-output-of-print-statements-using-adoconnection-in-delphi?rq=1 –

+0

Podría ser que su ADOQuery o ADOCommand se agote antes de recibir una respuesta del db? El valor predeterminado de CommandTimeOut es 30. –

+0

Defina el controlador TADOConnection.OnInfoMessage para procesar este mensaje desde el servidor SQL – valex

Respuesta

5

Aquí hay un ejemplo. Lo he probado con D7 y MSSQL2000. Y añade a MEMO1 todos los mensajes de servidor:

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). 

Además, si se tarda mucho tiempo en cuenta para implementar un bucle while no en el hilo principal.

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; 

que he encontrado this thread (Russian) de procedimiento almacenado y corregirlo para el comando BACKUP.

+0

El código anterior funcionaría con objetos Delphi nativos, si las envolturas delphi nativas no rompieron la intención de diseño mostrada arriba donde pasamos en RA, y recuperamos 'rs: = NextRecordSet (RA)'. –

+4

He probado lo anterior en Delphi 2007 y XE2, con MS SQL Server 2008 R2 y SQL Server 2012, y funciona allí también. Lo moví a un hilo de fondo, porque ese era siempre mi plan. Si alguien quiere una versión de componente de código abierto (enhebrada) de la anterior, por favor avíseme (la votación anticipada requiere menos espacio que los comentarios). –

+1

bien cuando haya un componente, publicaré un enlace aquí. –

Cuestiones relacionadas