Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Ein paar SQL Fragen ( stored procedure ) (https://www.delphipraxis.net/48092-ein-paar-sql-fragen-stored-procedure.html)

Sven Janssen 20. Jun 2005 17:36

Datenbank: Informix • Version: 7SE • Zugriff über: Luxena

Ein paar SQL Fragen ( stored procedure )
 
Moin,

1. Wie schreibe ich am elegantesten eine Abfrage in einer stored procedure, ob select etwas zurück geliefert hat. z.b die Anzahl der Reihen?
Mir geht es darum eine Weich in einer SP zu programmieren die entscheidet ob der Datensatz aktualisiert werden soll, oder neu hinzugefügt werden muss.

2. Wie kann ich einen String aufbereiten? Vergleichbar mit format() oder sprintf(). Mir geht es hier darum das ich aus der Zahl 1 den String "01" bekomme.

3. Wie wandel ich Zeichen in eine Zahl. Wie z.b unter C mit atoi()?

Sorry sind sicherlich stupide fragen, aber bin absoluter SQL Neuling. Hab hier zig Bücher um mich herumliegen und komme eigentlich ganz gut klar, aber an einigen Kleinigkeiten hängt es dann.

Sven

Albi 21. Jun 2005 10:13

Re: Ein paar SQL Fragen ( stored procedure )
 
Hallo,

zu 1.)

Ich löse das immer so, dass ich die Datensätze über die ID identifiziere. Beim Speichern übergebe ich die ID an die SP, wenn die ID > 0 ist, dann wird ein Update durchgeführt und wenn eben ID = 0 ist, dann wird ein neuer DS angelegt.

SQL-Code:
(if ID = 0 Then)
begin
  Insert into .....

  select Gen_ID(DB_Gen_ID,1) From RDB$database
  Into :ID
end
else
begin
  Update DB Set ....
  WHERE ID = ID
end;

Sven Janssen 21. Jun 2005 12:06

Re: Ein paar SQL Fragen ( stored procedure )
 
Wenn ich ehrlich bin verstehe ich das nicht ganz.
Was ist ID? Du meinst den eindeutigen Schlüssen in der Tabelle oder?
Sprich ich mach ein Select auf einen Datensatz wo ich mir nur den Eindeutigen Schlüssen zurückgeben lasse und frage diesen ab.
Muss ich mal antesten.

Übrigens ich spreche nur von SQL Code, nicht von Abfragen in Pascal.
Dein Code schaut mir sehr Pascal lastig mit begin und end im if Zweig aus.

Vielen dank für die Antwort.

Sven

Albi 21. Jun 2005 12:31

Re: Ein paar SQL Fragen ( stored procedure )
 
Hallo,

ich kann mich jetzt auch irren aber ich glaube Du hast mich nicht verstanden.

Wenn Du dein Prog startest ist die ID (Primarykey aus der DB) = 0, da ja noch kein Datensatz ausgewählt wurde. Wenn Du nun eine Datensatz auswählst, übergibst Du auch den die ID (PK). Somit weist Du schonmal ob der Datensatz neu ist oder schon bereits existiert.

Die If-Abfrage ist das einzigste was mit Pascal zutun hat, der Rest ist doch reines SQL, oder nicht? :gruebel:

Wenn Du keine If-Abfrage haben willst, dann must Du vorher ein Select abschicken und das Ergebnis auswerten. Aber ich habe mich damit mal angeschmiert und bevorzuge daher diese Variante. Aber das ist ja jedem selber überlassen wie man regelt. Es gib bestimmt auch noch andere Wege, als die beiden hier zur Auswahl stehenden Varianten.

Hansa 21. Jun 2005 12:35

Re: Ein paar SQL Fragen ( stored procedure )
 
Die ID wird verwendet zur Identifizierung eines Records, ohne hierfür ein eventuell sogar vom User veränderbares Feld zu nehmen, z.B. die Art.Nr. Das führt aber jetzt zu weit. Was Albi da schreibt ist aber grober Unfug !! Der Wert des Generators enthält nie und nimmer die Anzahl der Reihen einer Table sofern auch nur ein Datensatz gelöscht wird ! Um es mal ganz klar zu sagen. Der Generatorwert ist völlig uninteressant, um Information damit zu verwalten. Gerade bei der ID geht es genau darum, es nicht so zu machen. Das Pascal-ähnliche ist aber doch auch gut so oder nicht ? Das Albi-Beispiel kommt mir übrigens sehr bekannt vor. Hatte mal irgendwann gepostet, wie man die DB automatisch entscheiden läßt, ob Insert oder Update gemacht werden muß. Allerdings, dafür eine Systabelle zu benutzen ? :shock:

Albi 21. Jun 2005 12:46

Re: Ein paar SQL Fragen ( stored procedure )
 
Hallo Hansa,

Das was ich hier beschrieben habe bezieht sich auf das hier

Zitat:

Zitat von Sven Janssen
Mir geht es darum eine Weich in einer SP zu programmieren die entscheidet ob der Datensatz aktualisiert werden soll, oder neu hinzugefügt werden muss.

Das man so nicht die Reihen bekommt ist mir auch schon bewusst.

Hansa 21. Jun 2005 13:00

Re: Ein paar SQL Fragen ( stored procedure )
 
Ah ja, habe ich vor Entsetzen gar nicht gesehen. :mrgreen: Trotzdem : Finger weg von den Systemtabellen wenn es anders auch geht ! Genau das werden nämlich die Programme, die bei einem Wechsel der Datenbank-Version plötzlich nicht mehr gehen. Das ist ähnlich zu sehen, wie die beliebten Programme, die direkt auf die WinApi zugreifen.

Sven Janssen 21. Jun 2005 13:32

Re: Ein paar SQL Fragen ( stored procedure )
 
Ne moment. Mein Programm soll darauf gar keine Berücksichtigung finden.
D.h das soll alles komplett losgelöst von der Applikation sein.
Ich möchte der Stored Procedure auch nicht mitgeben ob es ein insert oder update fahren soll, sondern das soll ganz alleine die SP entscheiden.

Was ich eigentlich nur benötige ist, das ich in der SP durch ein select oder sonst etwas heraus bekommen wieviele Datensätze (rows) das select gefunden hat.
Dadurch soll entschieden werden ob ein insert oder update ausgeführt werden soll.

Sven

Hansa 21. Jun 2005 13:56

Re: Ein paar SQL Fragen ( stored procedure )
 
Zitat:

Zitat von Sven Janssen
Ne moment. Mein Programm soll darauf gar keine Berücksichtigung finden.

So solls auch sein.

Zitat:

Zitat von Sven Janssen
Dadurch soll entschieden werden ob ein insert oder update ausgeführt werden soll.

Der Ansatz ist richtig, aber der Denkfehler ist der, daß du versuchst die Anzahl der Records zu ermitteln, anstatt ob gerade der betreffende Record schon da ist ! Dabei spielen jetzt allerdings die IDs eine entscheidende Rolle.

Sofern jeder DS eine eindeutige Nr. hat, dann brauchst Du nur...

Beispiel ist besser:

SQL-Code:
CREATE PROCEDURE PREISSP (
    ID_KUNDE INTEGER,
    VP DECIMAL(15,2),
    ID_ART INTEGER)
AS
DECLARE VARIABLE AENDERN INTEGER;
begin
  AENDERN = -1;
  select ID from PREIS where (ID_KUNDE= :ID_KUNDE) and
                             (ID_ART= :ID_ART)
  into :AENDERN;
  if (AENDERN < 0) then begin
    insert into PREIS (ID_KUNDE,ID_ART,VP)
           values (:ID_KUNDE,:ID_ART,:VP);
  end
  else begin
    update PREIS set VP=:VP
    where (ID_ART= :ID_ART) and (ID_KUNDE= :ID_KUNDE);
  end
  suspend;
end
Es geht um eine Kunden-Preistable. Hat ein Kunde für einen Artikel einen Preis, so ist die ID <> 0 => Update. Ist keiner da, dann bleibt Aendern auf -1 stehen und es wird ein Insert gemacht. Bingo !

Sven Janssen 21. Jun 2005 15:16

Re: Ein paar SQL Fragen ( stored procedure )
 
das ist mal ne Antwort :-)
Das ganze muss also mit INTO stattfinden.
Ich dachte eher an :
Delphi-Quellcode:
let c = (select * from x where y = z);
Aber knapp vorbei ist auch daneben.

Was mich eben etwas verwirrt hat war das if ... then begin ... end
In meiner schlauen Informix SQL Guide steht etwas von if then ... end if

Zu meinen zwei anderen Fragen hast aber keine Antwort parat oder?

Sven

Hansa 21. Jun 2005 18:46

Re: Ein paar SQL Fragen ( stored procedure )
 
Ne, keine Antwort. 8) Du wirst doch wohl wissen, ob das Programm eine Zahl oder einen string aus der DB erwartet ? Und das mußt du der auch mitteilen !

Sven Janssen 21. Jun 2005 19:07

Re: Ein paar SQL Fragen ( stored procedure )
 
Was?
Bitte nicht hinterfragen, ich denke mir schon meinen Teil dabei ;-)
Es geht nicht um Werte die ich aus oder in die SQL Tabelle schreibe, sondern um Schlüssel die ich in den Stored Procedures aufbereiten muss.
Ich habe SQL in a Nutshell von o'reilly. Ich kann Sinus, Cosinus und sonstwas in einigen SQL Datenbanksystemen aufbereiten. Aber simple Dinge finde ich nicht.

Die Datenstruktur auf die ich Zugreife ist Asbach Uralt. Aber diese kann nicht erneuert werden, da sonst über 100 Programme mit Millionen Zeilen von Code geändert werden müssen. Nun soll von _aussen_ Windows Programme über Informix auf die Daten zugreifen. Auch alles kein Problem. Aber die Datenstrukturen sind nicht wirklich SQL tauglich. ( die Stammen noch aus Altos Zeiten ;-) falls dir das was sagt *hehe*)

Ich muss in der SP also Schlüssel aufbereiten nach dem System "nummer+laufende Positon" . z.b 1000001 bis 1000099
Aber wie soll ich das ohne sprintf/format elegant lösen? Ich könnte das zwar alles im Programmcode lösen, aber dann verursache ich unnötigen Traffic den ich vermeiden möchte, da die Programme nachher über <1MBit Standleitungen laufen sollen.

So pervers das nun anzuschauen sein soll müsste ich so etwas in der Art lösen ( code so aus dem Kopf geschrieben )
Delphi-Quellcode:
found = -1;
for i = 0 to 99 do
  key = format('%s%.02d',[suche,i]); -- das suche ich in SQL
  select nummer from table where nummer = key into erg
  if erg <= 0 then
    found = i;
    exit for;
  end if
end for
if found > 0 then
  -- Luecke gefunden nun neuen Datensatz in luecke einfuegen
end if
Bitte nicht über den Sinn diskutieren ;-) einfach so hinnehmen

Sven

marabu 21. Jun 2005 19:52

Re: Ein paar SQL Fragen ( stored procedure )
 
Hallo Sven,

ich habe keine Ahnung was Informix kann, aber ich würde etwa so vorgehen:

Du übergibst neben den Feldwerten noch deinen Suchbereich sb an deine Stored Procedure. In deinem Beispiel wäre sb = 10000. In deiner SP würdest du als erstes die Grenzen deines Suchbereiches festlegen:

SQL-Code:
lBound = :sb * 100 + 1
uBound = :sb * 100 + 98
Anschließend kannst du einen Cursor definieren für:

SQL-Code:
DECLARE c CURSOR FOR
SELECT nummer + 1 AS freienummer FROM tabelle o
WHERE o.nummer between lBound and uBound
AND NOT EXISTS (
  SELECT i.nummer FROM tabelle i WHERE i.nummer = o.nummer + 1
)
Dieser Cursor listet dir alle freien Nummern im Range ...01 bis ...99, aber du kannst eventuell den result set auf ein singleton limitieren.

Grüße vom marabu

Sven Janssen 21. Jun 2005 19:58

Re: Ein paar SQL Fragen ( stored procedure )
 
das schaut nett und viel versprechend aus.
Werde ich morgen früh direkt man austesten.

Danke :-)

Sven

Sven Janssen 22. Jun 2005 13:20

Re: Ein paar SQL Fragen ( stored procedure )
 
Toll. Informix 7 SE bekommt es nicht hin Cursors zu benutzen.
So wie das ausschaut geht das nur über ESQL und dieses wird nur über direkte Zugriffe über deren eigenen Schnittstellen gelöst :-(

Zumindestens lösen DECLARE PREPARE usw nur Syntax Erros aus.

Sven

marabu 22. Jun 2005 14:11

Re: Ein paar SQL Fragen ( stored procedure )
 
Hallo Sven,

ist es nicht so, dass du eine stored procedure in Informix SPL erstellen musst? Aus einem Handbuch habe ich das hier:

SQL-Code:
CREATE_PROCEDURE increase_by_pct( pct INTEGER )
   DEFINE s INTEGER;
   FOREACH sal_cursor FOR
      SELECT salary INTO s FROM employee
         WHERE salary > 35000
      LET s = s + s * ( pct/100 );
      UPDATE employee SET salary = s
         WHERE CURRENT OF sal_cursor;
   END FOREACH
END PROCEDURE;
Sieht doch gar nicht so schlimm aus...

marabu

Sven Janssen 22. Jun 2005 14:36

Re: Ein paar SQL Fragen ( stored procedure )
 
Das funktioniert tatsächlich.
Aber laut Informix SQL Guide und Informix SQL Referenz sollte das eher so

Delphi-Quellcode:
declare c_master cursor with hold for
select customer_num from customer where city = 'Pittsburgh';
oder
Delphi-Quellcode:
prepare st_1 from
    'select order_date from orders where customer_num = ? for update';
declare c_detail cursor for st_1;
so ausschauen.

Und beide Varianten gehen mittel dbaccess nicht.

Sven


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:00 Uhr.

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