2008-10-31 8 views
10

मेरी एमएस एसक्यूएल संग्रहित प्रक्रियाओं में से कुछ में ADOConnection का उपयोग कर 'प्रिंट' बयान के उत्पादन में देखें 'प्रिंट' आदेश का उपयोग कर संदेशों का उत्पादन। मेरे डेल्फी 2007 एप्लिकेशन में, जो TADOConnection का उपयोग कर एमएस एसक्यूएल से जुड़ता है, मैं उन 'प्रिंट' कमांड के आउटपुट को कैसे देख सकता हूं?डेल्फी

कुंजी आवश्यकताओं: 1) मैं क्वेरी एक बार से अधिक नहीं चला सकते हैं; यह चीजों को अद्यतन कर सकता है। 2) मुझे डेटा प्रिंट होने पर भी 'प्रिंट' परिणाम देखने की आवश्यकता है।

उत्तर

9

एक दिलचस्प एक था कि ...
ADOConnection कार्यों से OnInfoMessage घटना लेकिन शैतान विवरण में है!

मुख्य अंक:
उपयोग CursorLocation = clUseServer डिफ़ॉल्ट clUseClient के बजाय।
अपने ADOStoredProc के साथ ओपन और नहीं ExecProc का उपयोग करें।
निम्नलिखित प्राप्त करने के लिए वर्तमान से अगलाRecordset का उपयोग करें, लेकिन यह सुनिश्चित करना सुनिश्चित करें कि आपके पास एक खुला है।
अपनी संग्रहीत प्रक्रिया में SET NOCOUNT = ON का उपयोग करें।

एसक्यूएल पक्ष: अपने संग्रहीत प्रक्रिया

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 

डेल्फी पक्ष:
एक नया VCL बनाएं आवेदन पत्र।
अपने फॉर्म में एक मेमो और एक बटन रखें।

कॉपी निम्नलिखित पाठ, सूची बदल सकते हैं और डेटा स्रोत और अपने फार्म पर पेस्ट करें

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 

ADOConnection की OnInfoMessage में

Memo1.Lines.Add(Error.Description); 

डाल ButtonClick के लिए, यह कोड पेस्ट

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; 
+0

यह निश्चित रूप से मुझे सही रास्ते पर रखता है: लचीलापन के लिए, मैंने एक TADOStoredProc के बजाय एक TADOCommand का उपयोग किया, और यह अभी भी काम करता है। SET NOCOUNT चालू भी वैकल्पिक प्रतीत होता है: यदि आपके पास यह नहीं है तो यह केवल अतिरिक्त संदेशों को प्रिंट करता है।और clUseServer रिकॉर्डिंग को TDBGrid में अनुपयोगी बनाता है :( – apenwarr

+1

उपरोक्त ऑनिनफ़ोमेज़ कोड केवल पहला प्रिंट संदेश दिखाता है। उन सभी को प्रिंट करने के लिए (उदाहरण के लिए यदि चयन विवरणों के बीच 1 से अधिक PRINT स्टेटमेंट हैं) यह करें: var i: पूर्णांक; मैं के लिए शुरू : -; cxMemo1.Lines.Add ( ADOConnection1.Errors.Item [i = 0 AdoConnection1.Errors.Count को 1 शुरू // cxMemo1.Lines.Add (Error.Description) करना ]। डिस्क्रिप्शन); अंत; अंत; –

1

मुझे लगता है कि संभव है न। प्रिंट विवरणों को डंप करने और परिणामों के साथ इसे वापस करने के लिए आप एक temp तालिका का उपयोग कर सकते हैं।

3

.net के कनेक्शन की कक्षाओं में एक घटना InfoMessage कहा जाता है। इस घटना के लिए एक हैंडलर में आप ईवेंट तर्क से InfoMessage (प्रिंट स्टेटमेंट) पुनर्प्राप्त कर सकते हैं।

मेरा मानना ​​है कि डेल्फी एक ऐसी ही घटना "OnInfoMessage" कहा जाता है कि आप में मदद मिलेगी है।

+1

यह करीब है! यह काम करता है अगर मैं कमांड सेट करता हूं। निष्पादन विकल्प = [eoExecuteNoRecords]। लेकिन यह मुझे किसी भी डेटासेट प्राप्त करने से रोकता है। हम्म ... – apenwarr

0

फ्रैंकोइस कोड (जैसा कि डीएक्सई 2 के साथ परीक्षण किया गया) में कुछ सुधार कई प्रिंट स्टेटमेंट्स और चयनों की एक चर संख्या से परिणाम के लिए। परिवर्तन सूक्ष्म हैं।

procedure TForm1.ADOConnection1InfoMessage(Connection: TADOConnection; 
    const Error: Error; var EventStatus: TEventStatus); 
var 
    i: integer; 
begin 
    // show ALL print statements 
    for i := 0 to AdoConnection1.Errors.Count - 1 do 
    begin 
    // was: cxMemo1.Lines.Add(Error.Description); 
    cxMemo1.Lines.Add(
     ADOConnection1.Errors.Item[i].Description); 
    end; 
end; 

procedure TForm1.cxButton1Click(Sender: TObject); 
const 
    adStateOpen = $00000001; // or uses ADOInt 
var 
    records: Integer; 
    ARecordSet: _RecordSet; 
begin 
    cxMemo1.Lines.Add('=========================='); 

    ADOStoredProc1.Open; 

    try 
    ARecordSet := ADOStoredProc1.RecordSet; // initial fetch 
    while Assigned(ARecordSet) do 
    begin 
     // assign the recordset to a DataSets recordset to traverse 
     AdoDataSet1.Recordset := ARecordSet; 
     // do whatever with current ARecordSet 
     while not ADODataSet1.eof do 
     begin 
     cxMemo1.Lines.Add(ADODataSet1.Fields[0].FieldName + 
      ': ' + ADODataSet1.Fields[0].Value); 
     AdoDataSet1.Next; 
     end; 
     // fetch next recordset if there is one 
     ARecordSet := ADOStoredProc1.NextRecordSet(records); 
     if Assigned(ARecordSet) and ((ARecordSet.State and adStateOpen) <> 0) then 
     ADOStoredProc1.Recordset := ARecordSet 
     else 
     Break; 
    end; 
    finally 
    ADOStoredProc1.Close; 
    end; 

end;