Eso fue muy interesante ...
El evento OnInfoMessage de ADOConnection funciona pero el Demonio está en los detalles!
puntos principales:
uso CursorLocation = clUseServer en lugar de la clUseClient por defecto.
use Open y no ExecProc con su ADOStoredProc.
use NextRecordset del actual para obtener lo siguiente, pero asegúrese de verificar que tenga uno abierto.
use SET NOCOUNT = ON en su procedimiento almacenado.
lado SQL: el procedimiento almacenado
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[FG_TEST]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[FG_TEST]
GO
-- =============================================
-- Author: François
-- Description: test multi ADO with info
-- =============================================
CREATE PROCEDURE FG_TEST
AS
BEGIN
-- SET NOCOUNT ON absolutely NEEDED
SET NOCOUNT ON;
PRINT '*** start ***'
SELECT 'one' as Set1Field1
PRINT '*** done once ***'
SELECT 'two' as Set2Field2
PRINT '*** done again ***'
SELECT 'three' as Set3Field3
PRINT '***finish ***'
END
GO
lado Delphi:
Crear un nuevo VCL formularios de solicitud.
Ponga una nota y un botón en su formulario.
copiar el siguiente texto, cambiar el Catálogo y origen de datos y pegarla en su Formulario
object ADOConnection1: TADOConnection
ConnectionString =
'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security In' +
'fo=False;Initial Catalog=xxxYOURxxxDBxxx;Data Source=xxxYOURxxxSERVERxxx'
CursorLocation = clUseServer
LoginPrompt = False
Provider = 'SQLOLEDB.1'
OnInfoMessage = ADOConnection1InfoMessage
Left = 24
Top = 216
end
object ADOStoredProc1: TADOStoredProc
Connection = ADOConnection1
CursorLocation = clUseServer
ProcedureName = 'FG_TEST;1'
Parameters = <>
Left = 24
Top = 264
end
En el OnInfoMessage del ADOConnection poner
Memo1.Lines.Add(Error.Description);
Para el ButtonClick, pega este código
procedure TForm1.Button1Click(Sender: TObject);
const
adStateOpen = $00000001; // or defined in ADOInt
var
I: Integer;
ARecordSet: _Recordset;
begin
Memo1.Lines.Add('==========================');
ADOStoredProc1.Open; // not ExecProc !!!!!
ARecordSet := ADOStoredProc1.Recordset;
while Assigned(ARecordSet) do
begin
// do whatever with current RecordSet
while not ADOStoredProc1.Eof do
begin
Memo1.Lines.Add(ADOStoredProc1.Fields[0].FieldName + ': ' + ADOStoredProc1.Fields[0].Value);
ADOStoredProc1.Next;
end;
// switch to subsequent RecordSet if any
ARecordSet := ADOStoredProc1.NextRecordset(I);
if Assigned(ARecordSet) and ((ARecordSet.State and adStateOpen) <> 0) then
ADOStoredProc1.Recordset := ARecordSet
else
Break;
end;
ADOStoredProc1.Close;
end;
Esto definitivamente me puso en el camino correcto: para mayor flexibilidad, utilicé un TADOCommand en lugar de un TADOStoredProc, y todavía funciona. SET NOCOUNT ON también parece ser opcional: solo imprime mensajes extra si no lo tiene.Y clUseServer hace que los conjuntos de registros no se puedan utilizar en una TDBGrid :( – apenwarr
El código OninfoMessage anterior solo muestra el primer mensaje PRINT. Para imprimirlos todos (por ejemplo, si hay más de 1 PRINT declaraciones entre las instrucciones SELECT), haga esto: var i: entero; comienzan para i: = 0 a AdoConnection1.Errors.Count - 1 hacer comienzan // cxMemo1.Lines.Add (Error.Description); cxMemo1.Lines.Add ( ADOConnection1.Errors.Item [i ] .Description); end; end; –