2009-05-29 11 views
3

Pardonnez ma naïveté, mais je suis nouveau à l'utilisation de Delphi avec des bases de données (ce qui peut sembler étrange à certains).Comment puis-je renvoyer toutes les valeurs d'une procédure stockée?

J'ai configuré une connexion à ma base de données (MSSQL) en utilisant une connexion TADOConnection. J'utilise TADOStoredProc pour accéder à ma procédure stockée.

Ma procédure stockée renvoie 2 colonnes, une colonne remplie de noms de serveurs et une deuxième colonne remplie d'utilisateurs sur le serveur. Il renvoie généralement environ 70 enregistrements ... pas beaucoup de données.

Comment est-ce que j'énumère cette procédure stockée par programme? Je suis capable de déposer un DBGrid sur mon formulaire et de l'attacher à un TDataSource (qui est ensuite attaché à mon ADOStoredProc) et je peux vérifier que les données sont correctement récupérées.

Idéalement, je voudrais énumérer les données renvoyées et les déplacer dans une TStringList.

Actuellement, je suis en utilisant le code suivant pour énumérer le ADOStoredProc, mais il ne s @RETURN_VALUE 'retours:

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; 

Répondre

8

Appel ouvert pour obtenir un ensemble de données retourné

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

N'utilisez pas de FieldByName dans la boucle! Vous pouvez définir des champs au moment du design ou créer un objet Field entre les boucles Open et while. –

+2

J'ai expressément choisi cette route pour plus de clarté. Mais dans le post, il faisait référence à deux colonnes et à 70 lignes donc ce n'est pas un gros frais généraux même si vous l'avez fait de cette façon. Cependant, je n'utilise jamais les champs définis lors de la conception ou créer un objet de champ comme vous le suggérez. Si vous voulez minimiser les frais généraux, vous pouvez référencer les champs par position ordinale, ce qui est ma préférence sur les champs définis. –

0

Jetez un oeil à cette (juste googlé):

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

Fondamentalement, une procédure stockée SQL Server renvoie toujours une valeur de retour, mais elle peut également créer un ensemble de résultats, que vous devez traiter comme l'ensemble de données renvoyé par une instruction select régulière.

2

Si votre procédure stockée renvoie un jeu de résultats (lignes de données), n'utilisez pas ExecProc. Il est conçu pour exécuter des procédures sans jeu de résultats. Utilisation ouverte ou active à la place, et vous pouvez les traiter comme vous utilisez des paramètres:

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, appelant ouvert, puis provoque ExecProc problèmes; Open renvoie un jeu de résultats, ExecProc l'efface car vous exécutez la procédure une deuxième fois sans résultat attendu. Je ne pense pas non plus que vous ayez besoin de Parameters.Refresh, mais je n'en suis pas sûr à 100%.

+1

Est-il important que le SP renvoie un jeu de résultats lorsque le code parcourt la collection de paramètres? Autrement dit, ce code ne renverra-t-il pas le même résultat que les OP? (avertissement: je ne suis pas un programmeur Delphi, donc peut-être que je ne comprends pas la question ...) – Matt

+0

Bien sûr, c'est important. L'OP obtenait un resultset avec Open, puis l'abandonnait avec ExecSQL, ne laissant rien à faire. Supprimer ExecSQL et utiliser Open (ou Active: = True) laisse un ensemble de résultats pour itérer. IOW, ce n'est pas le même résultat que les OP. :-) –

+0

Si je ne suis pas malentendu, l'OP veut que les enregistrements ne soient pas les paramètres. Il veut essentiellement obtenir par programme ce qui est retourné dans le DBGrid. –

3

Utilisez Ouvrir pour obtenir les enregistrements de la StoredProc
Utilisez soit la conception-temps Les champs, ad-hoc Les champs saisi avec FieldByName avant que la boucle ou des champs [nn ] pour obtenir les valeurs.

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

Note: Les champs [nn] permet d'écrire moins de code, mais méfiez-vous si le StoredProc change l'ordre des colonnes retournées.

Questions connexes