Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Fehler beim ausführen einer SP (Param nicht bereitgestellt) (https://www.delphipraxis.net/107836-fehler-beim-ausfuehren-einer-sp-param-nicht-bereitgestellt.html)

Sharky 3. Feb 2008 08:11

Datenbank: SQL Express • Version: 2003 • Zugriff über: ADO

Fehler beim ausführen einer SP (Param nicht bereitgestellt)
 
Hai,

irgendwie scheine ich mich zu dumm anzustellen.

Ich möchte über eine SP Daten in eine Tabelle eintragen und die ID des letzten Datensatzes zurück bekommen.

Meine SP sieht so aus:
SQL-Code:
USE [schluessel]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE Procedure [dbo].[Benutzer_Neu] @vorname VarChar (50), @nachname VarChar(50), @anmeldename VarChar(50), @kennwort VarChar(50), @lastID int output
as
begin
   set nocount on
   insert into benutzer (vorname, nachname, anmeldename, kennwort)
   Values (@vorname, @nachname, @anmeldename, @kennwort)
   select @lastID = @@Identity
   set nocount on
end
Wenn ich das über die Managementkonsole teste funktionert das auch.

In Delphi rufe ich das dann so auf:
Delphi-Quellcode:
procedure TMain_Form.Button1Click(Sender: TObject);
var
  lastID : Integer;
begin
  with DataModule1.ADOStoredProc1 do
  begin
    Parameters.Refresh;
    Parameters.ParamValues['@vorname'] := 'Vorname';
    Parameters.ParamValues['@nachname'] := 'Nachname';
    Parameters.ParamValues['@anmeldename'] := 'Anmeldename';
    Parameters.ParamValues['@kennwort'] := 'Kennwort';
    ExecProc;
    lastID := Parameters.ParamValues['@lastID'];
  end;
end;
Aber ich bekomme immer diese Fehlermeldung:
Die Prozedur oder Funktion 'Benutzer_Neu' erwartet den '@lastID'-Parameter, der nicht bereitgestellt wurde.

Codewalker 3. Feb 2008 09:12

Re: Fehler beim ausführen einer SP (Param nicht bereitgestel
 
Der Parameter ist ja beim Aufruf null. Auch wenn du ihn nicht brauchst, hast du schonmal versucht ihm trotzdem einen Wert mitzugeben? Alternativ könntest du auch eine Stored Function daraus machen, die als Ergebnis die ID zurückliefert.

marabu 3. Feb 2008 09:21

Re: Fehler beim ausführen einer SP (Param nicht bereitgestel
 
Moin Stephan,

der Fehler steckt nicht in der Benutzung der StoredProc, sondern in der Vorbereitung:

Delphi-Quellcode:
begin
  spBenutzerNeu := TADOStoredProc.Create(nil);
  with spBenutzerNeu do
  begin
    Connection := SqlConnection;
    ProcedureName := 'Benutzer_Neu;1';
    Parameters.CreateParameter('@vorname', ftString, pdInput, 50, '');
    Parameters.CreateParameter('@nachname', ftString, pdInput, 50, '');
    Parameters.CreateParameter('@anmeldename', ftString, pdInput, 50, '');
    Parameters.CreateParameter('@kennwort', ftString, pdInput, 50, '');
    Parameters.CreateParameter('@lastid', ftInteger, pdOutput, 0, 0);
    Prepared := True;
  end;
end;
Freundliche Grüße

alzaimar 3. Feb 2008 09:27

Re: Fehler beim ausführen einer SP (Param nicht bereitgestel
 
Wie hast Du deine TADOStoredProcedure initialisiert? Ich meine, im Designer? Doppelklick auf die Params-Eigenschaft und prüfe, ob alle Parameter vorhanden sind. Wenn nicht, gib in der Eigenschaft 'ProcedureName' einen anderen Namen ein und drücke ENTER. Nun liest ADO die Parameter-Definition für diese SP neu ein. Anschließend gibtst du wieder den "Benutzer_Neu" ein und prüfst die Params-Eigenschaft. Das sollte funktieren.

marabu zeigt, wie man es zur Laufzeit macht.

Wenn nicht, schließt Du im Designer die TADOConnection und baust sie wieder auf (Connected: False und wieder True). Dann wiederholst Du o.g. Prozedere. Dann klappt es garantiert.

@Codewalker: Ein Parameter kann doch den Wert NULL haben. Das Problem ist, das der Parameter nicht in der Params-Collection vorhanden ist.

Tipp: Verwende immer einen Profiler/Monitor, wenn Du mit einer DBMS arbeitest. Dann siehst du genau, was ADO für einen Murks zusammenbastelt.

Codewalker 3. Feb 2008 09:49

Re: Fehler beim ausführen einer SP (Param nicht bereitgestel
 
@alzaimar: Was sind denn das für Profiler? Gibt's dir für alle DBMS (konkret: Oracle (denke doch schon)).

Sharky 3. Feb 2008 14:10

Re: Fehler beim ausführen einer SP (Param nicht bereitgestel
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hai ihr,

danke für die Antworten.

Mit dem Code von marabu funktioniert es. Ich hatte es auch schon gemacht die Parameter von Hand zu erzeugen. Aber warum geht es nicht wenn ich "einfach" die Parameter mit Parameters.Refresh abfrage.

@alzaimar: Schon zur Laufzeit sind die Parameter vorhanden (siehe Anhang) darum wundert es mich ja das ich die Fehlermeldung bekomme.

marabu 3. Feb 2008 15:09

Re: Fehler beim ausführen einer SP (Param nicht bereitgestel
 
Parameters.Refresh() scheint die Direction nicht erkennen zu können.

Sharky 3. Feb 2008 15:17

Re: Fehler beim ausführen einer SP (Param nicht bereitgestel
 
Zitat:

Zitat von marabu
Parameters.Refresh() scheint die Direction nicht erkennen zu können.

Hmmm... wenn ich das hier mache:
Delphi-Quellcode:
procedure TMain_Form.Button3Click(Sender: TObject);
var
  I: Integer;
begin
  with DataModule1.sp_benutzer_neu do
  begin
    Parameters.Refresh;
    for I := 0 to Parameters.Count - 1 do
    begin
      ListBox1.Items.Add(Format ('%s - %d',[Parameters[i].Name, Ord(Parameters[i].Direction)]));
    end;
  end;
end;
Kommt als Ergebniss:
Code:
@RETURN_VALUE - 4
@vorname - 1
@nachname - 1
@anmeldename - 1
@kennwort - 1
@lastID - 3
Dürfte doch stimmen.

marabu 3. Feb 2008 15:20

Re: Fehler beim ausführen einer SP (Param nicht bereitgestel
 
Nein, @lastid - 2 wäre richtig.

Sharky 3. Feb 2008 16:57

Re: Fehler beim ausführen einer SP (Param nicht bereitgestel
 
Zitat:

Zitat von marabu
Nein, @lastid - 2 wäre richtig.

Hai marabu,

so würde man denken ;-)
Aber wenn ich in deinem Beispiel oben:
Delphi-Quellcode:
Parameters.CreateParameter('@lastid', ftInteger, pdInputOutput, 0, 0);
eintrage (pdOutput durch pdInputOutput ersetzt) funktioniert es trotzdem ohne Fehler.

Wo ist der Unterschied ob das pdInputOutput via CreatParameter gesetzt wird oder ob es aus der SP kommt?

Aber irgend wie muss es daran liegen. Wenn ich meinen Code so ändere funktioniert es. Allerdings nur beim ersten Aufruf. Beim nächsten kommt eine Zugriffsverletzung in der sqloledb.dll :roll:
Delphi-Quellcode:
procedure TMain_Form.Button1Click(Sender: TObject);
begin
  with DataModule1.sp_benutzer_neu do
  begin
    Parameters.Refresh;
    Parameters.ParamByName('@lastID').Direction := pdOutput; // Direction für @lastID setzen.
    Parameters.ParamValues['@vorname'] := Edit1.Text;
    Parameters.ParamValues['@nachname'] := Edit2.Text;
    Parameters.ParamValues['@anmeldename'] := Edit3.Text;
    Parameters.ParamValues['@kennwort'] := Edit4.Text;
    Prepared := True;
    ExecProc;
    Edit5.Text := Parameters.ParamValues['@lastID'];
  end;
end;
Ich habe ja kein Problem die Parameter im Code zu definieren. Aber ich würde gerne verstehen warum es zu diesem Verhalten kommt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:01 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz