![]() |
Datenbank: MySql • Version: 5.6 • Zugriff über: egal
Variable in Function
Moin,
ich arbeite mich grade in MySql ein. Ich möchte eine Function erstellen, die aus einer Tabelle den aktuellen Wert holt, den Wert in der Tabelle hochzählt und den geholten Wert zurückgibt. Folgende Function hab ich erstellt:
Code:
Wenn ich die Function ausführe:
CREATE DEFINER=`root`@`localhost` FUNCTION `get_next_id`() RETURNS int(11)
BEGIN declare result int; select SEQUENCE_VALUE into @result from openjpa_sequence_table where id = 0; if (@result is null) then SET @result := 1; insert into openjpa_sequence_table (ID, SEQUENCE_VALUE) VALUES (0, 1); else update openjpa_sequence_table set SEQUENCE_VALUE = SEQUENCE_VALUE + 1 where ID = 0; end if; RETURN @result + 1; END
Code:
bekomme ich immer NULL als Result zurück. Ich bin ratlos, warum das so ist. In der Tabelle sind aktuell keine Datensätze, daher sollte die Function den entsprechenden Datensatz erstellen.
select @get_next_id;
In der Tabelle wird aber kein Datensatz erstellt. Daher vermute ich, dass der TRUE-Teil des If-Statements nicht ausgeführt wird. Ich bin ratlos... |
AW: Variable in Function
Auch wenn es nicht hilft. Im Falle '@Result is null' musst du @Result auf 0 setzen (und nicht auf 1).
|
AW: Variable in Function
Du suchst also eine Lösung für das "INSERT OR UPDATE"-Problem?
![]() ![]() Postgre SQL kennt z.B. die Variable FOUND, welche auf True steht, wenn z.B. ein vorheriges Update mindestens einen Datensatz "fand". Eventuell hat mySQL auch sowas oder was Ähnliches?
SQL-Code:
UPDATE db SET b = data WHERE a = key;
IF not FOUND THEN INSERT INTO db (a, b) VALUES (key, data); Oder man macht sich selber soeine Variable, wenn die vorhandene Variable (hier @Result) kein passendes Ergebnis liefert.
SQL-Code:
PS: Was passiert wohl, wenn zwischen dem SELECT und dem INSERT/UPDATE jemand Anderes ein INSERT/UPDATE macht?
declare result int;
declare jupp bool; select SEQUENCE_VALUE, true into @result, @jupp from openjpa_sequence_table where id = 0; if jupp is null then insert ... else update .. Oder führt MySQL diese FUNCTION quasi atomar aus, so daß kein Anderer zur selben Zeit was an der Tabelle machen kann? |
AW: Variable in Function
Hallo Nersgat,
warum deklarierst du eine Variable Result und benutzt sie dann nicht?
Code:
sollte funktionieren.
CREATE DEFINER=`root`@`localhost` FUNCTION `get_next_id`() RETURNS int(11)
BEGIN declare result int; select SEQUENCE_VALUE into result from openjpa_sequence_table where id = 0; if (result is null) then SET result := 1; insert into openjpa_sequence_table (ID, SEQUENCE_VALUE) VALUES (0, result); else SET result := result+1; update openjpa_sequence_table set SEQUENCE_VALUE = result where ID = 0; end if; RETURN result; END Und wenn du jetzt noch ein Select auf die Funktion und nicht auf eine Variable machst sollte es erst recht funktionieren
Code:
Gruß aus Dortmund
select get_next_id();
|
AW: Variable in Function
Erst einmal danke für die Antworten!
@gravedigger: ich dachte, das hätte ich getan? :gruebel: Wie würde ich den die von mir declarierte Variable referenzieren? |
AW: Variable in Function
Hallo Nersgatt,
die Variable @result ist eine Benutzervariable und muss nicht deklariert werden. Sie behält ihren Wert solange wie die MySQL-Session geöffnet ist und nicht überschrieben wird. So wie die Variable deklariert wurde sollte man sie auch benutzen
Code:
Gruß aus Dortmund
DECLARE result int;
SET result := result+1; |
AW: Variable in Function
Ah, mir war das Konzept dieser Benutzervariablen nicht geläufig. Das erklärt meine Fehler.
Jetzt funktioniert es so wie gewünscht! :thumb: @Dejan Vu: Deinen Hinweis hab ich natürlich auch gesehen und Du hast natürlich recht. Danke! |
AW: Variable in Function
Fein, und ich hab was über mysql gelernt.
|
AW: Variable in Function
Also abgesehen davon, daß
Code:
hier überfüssig ist
declare result int;
Code:
sollte doch mit einem
CREATE DEFINER=`root`@`localhost` FUNCTION `get_next_id`() RETURNS int(11)
BEGIN declare result int; select SEQUENCE_VALUE into @result from openjpa_sequence_table where id = 0; if (@result is null) then SET @result := 1; insert into openjpa_sequence_table (ID, SEQUENCE_VALUE) VALUES (0, 1); else update openjpa_sequence_table set SEQUENCE_VALUE = SEQUENCE_VALUE + 1 where ID = 0; end if; RETURN @result + 1; END
Code:
alles funktionieren, oder hab ich da etwas falsch verstanden?
select get_next_id ....
Gruß K-H P.S. soetwas wie SQUENCES oder AUTOINC gibt es in MySQL nicht? |
AW: Variable in Function
Zitat:
Damit es hier nicht zu Kollisionen kommt, ahme ich auf diese Weise das Verhalten des Persistenzframeworks nach. (*) ![]() |
AW: Variable in Function
Zitat:
![]() [edit] hmmmm :gruebel: |
AW: Variable in Function
[QUOTE=Nersgatt;1263235...Die Kollegen verwenden ein Persistenzframework (*), welches die Vergabe der IDs eben mit dieser Tabelle realisiert hat...[/QUOTE] Es sollte ein Gesetz gegen diesen Blödsinn geben. Das ist so dermaßen lahm... Egal. Esis wie esis
|
AW: Variable in Function
Zitat:
Ich finde es auch unglücklich, dies mit einer Tabelle zu machen, wenn die Datenbank dafür besser geeignete Mechanismen anbietet (wie z.B. Sequences). Aber in meinem Fall sind es halt Gegebenheiten, mit denen ich leben muss. |
AW: Variable in Function
Moin, Moin,
ich habe auf meiner mySQL Instance die fehlenden Sequencen aus der Oracle wie folgt "ersetzt" :
Code:
funktioniert recht gut !
DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `nextval`(`seq_name` varchar(100)) RETURNS bigint(20) BEGIN declare cur_val bigint(20); SELECT sequence_cur_value INTO cur_val FROM gemiii.sequence_data WHERE sequence_name = seq_name; IF cur_val IS NOT NULL THEN UPDATE gemiii.sequence_data SET sequence_cur_value = IF ( (sequence_cur_value + sequence_increment) > sequence_max_value, IF ( sequence_cycle = TRUE, sequence_min_value, NULL ), sequence_cur_value + sequence_increment ) WHERE sequence_name = seq_name; END IF; RETURN cur_val; END die Tabelle dazu sieht folgt aus : CREATE TABLE `sequence_data` ( `sequence_name` varchar(100) NOT NULL, `sequence_increment` int(11) unsigned NOT NULL DEFAULT '1', `sequence_min_value` int(11) unsigned NOT NULL DEFAULT '1', `sequence_max_value` bigint(20) unsigned NOT NULL DEFAULT '18446744073709551615', `sequence_cur_value` bigint(20) unsigned DEFAULT '1', `sequence_cycle` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`sequence_name`), UNIQUE KEY `sequence_name_UNIQUE` (`sequence_name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; Beste Grüße Michael |
AW: Variable in Function
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:15 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-2025 by Thomas Breitkreuz