![]() |
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 |
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; |
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 |
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. |
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:
|
Re: Ein paar SQL Fragen ( stored procedure )
Hallo Hansa,
Das was ich hier beschrieben habe bezieht sich auf das hier Zitat:
|
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.
|
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 |
Re: Ein paar SQL Fragen ( stored procedure )
Zitat:
Zitat:
Sofern jeder DS eine eindeutige Nr. hat, dann brauchst Du nur... Beispiel ist besser:
SQL-Code:
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 !
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 |
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:
Aber knapp vorbei ist auch daneben.
let c = (select * from x where y = z);
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 |
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 !
|
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:
Bitte nicht über den Sinn diskutieren ;-) einfach so hinnehmen
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 Sven |
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:
Anschließend kannst du einen Cursor definieren für:
lBound = :sb * 100 + 1
uBound = :sb * 100 + 98
SQL-Code:
Dieser Cursor listet dir alle freien Nummern im Range ...01 bis ...99, aber du kannst eventuell den result set auf ein singleton limitieren.
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 ) Grüße vom marabu |
Re: Ein paar SQL Fragen ( stored procedure )
das schaut nett und viel versprechend aus.
Werde ich morgen früh direkt man austesten. Danke :-) Sven |
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 |
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:
Sieht doch gar nicht so schlimm aus...
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; marabu |
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:
oder
declare c_master cursor with hold for
select customer_num from customer where city = 'Pittsburgh';
Delphi-Quellcode:
so ausschauen.
prepare st_1 from
'select order_date from orders where customer_num = ? for update'; declare c_detail cursor for st_1; 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