2009-05-29 49 views
3

原谅我的天真,但我对使用Delphi与数据库(这可能看起来有些奇怪)是新手。如何返回存储过程中的所有值?

我已经使用TADOConnection建立了与我的数据库(MSSQL)的连接。我正在使用TADOStoredProc来访问我的存储过程。

我的存储过程返回2列,一列填满服务器名称,第二列填满服务器上的用户。它通常返回大约70条记录......不是很多数据。

如何以编程方式枚举此存储过程?我能够在我的表单上放置一个DBGrid并将其附加到TDataSource(然后附加到我的ADOStoredProc),并且我可以验证数据是否正确检索。

理想情况下,我想枚举返回的数据并将其移入TStringList。

目前,我使用下面的代码来枚举ADOStoredProc,但它只返回 '@RETURN_VALUE':

ADOStoredProc1.Open; 
ADOStoredProc1.ExecProc; 
ADOStoredProc1.Parameters.Refresh; 

for i := 0 to AdoStoredProc1.Parameters.Count - 1 do 
begin 
    Memo1.Lines.Add(AdoStoredProc1.Parameters.Items[i].Name); 
    Memo1.Lines.Add(AdoStoredProc1.Parameters.Items[i].Value); 
end; 

回答

8

调用open得到一个数据集返回

StoredProc.Open; 
while not StoredProc.EOF do 
begin 
    Memo1.Lines.Add(StoredProc.FieldByName('xyz').Value); 
    StoredProc.Next; 
end; 
0

看看这个(只是GOOGLE了它):

[http://www.scip.be/index.php?Page=ArticlesDelphi12&Lang=EN#Procedure][1] 

基本上,SQL Server存储过程总是返回一个返回值,但它也可以创建一个结果集,您需要像从常规select语句返回的数据集那样处理结果集。

2

如果您的存储过程返回结果集(数据行),请不要使用ExecProc。它旨在执行没有结果集的过程。使用开放式或主动代替,然后就可以处理它们,就像你使用参数:

ADOStoredProc.Open; 

for i := 0 to ADOStoredProc1.Parameters.Count - 1 do 
begin 
    Memo1.Lines.Add(ADOStoredProc1.Parameters.Items[i].Name); 
    Memo1.Lines.Add(ADOStoredProc1.Parameters.Items[i].Value); 
end; 

BTW,调用打开,然后ExecProc引起的问题; Open返回一个结果集,然后ExecProc将清除它,因为您第二次运行该过程而没有预期的结果集。我也不认为你需要参数。刷新,但我不是100%肯定的。

+1

当代码循环访问Parameters集合时SP是否返回结果集是否重要?即这个代码不会返回与OP相同的结果吗? (免责声明:我不是Delphi程序员,所以也许我误解了这个问题......) – Matt 2009-05-29 23:44:09

+0

当然很重要。 OP使用Open获得结果集,然后使用ExecSQL丢弃结果集,不留任何循环。删除ExecSQL并使用Open(或Active:= True)会留下结果集进行迭代。 IOW,这与OP的结果并不相同。 :-) – 2009-05-29 23:54:03

3

使用打开,从StoredProc
使用或者设计时字段得到记录,即席场抢下与FieldByName循环或字段[NN前]来获取值。

procedure GetADOResults(AStoredProc: TADOStoredProc; AStrings: TStrings); 
var 
    fldServer, fldUser: TField; 
begin 
    AStoredProc.Open; 
    fldServer := AStoredProc.FieldByName('ServerName'); 
    fldUser := AStoredProc.FieldByName('User'); 
    while not AStoredProc.EOF do 
    begin 
    AStrings.Add(Format('Server: %s -/User: %s',[fldServer.AsString, fldUser.AsString])); 
    // or with FFields and Index (asumming ServerName is the 1st and User the 2nd) and no local vars 
    AStrings.Add(Format('Server: %s -/User: %s',[AStoredProc.Fields[0].AsString, AStoredProc.Fields[1].AsString])); 
    AStoredProc.Next; 
    end; 
end; 


//use like 
    GetADOResults(ADOStoredProc1, Memo1.Lines); 

注意:Fields [nn]允许编写较少的代码,但要注意StoredProc是否更改返回列的顺序。