Seltsames Problem mit Storedprocedure

Seltsames Problem mit Storedprocedure

am 11.08.2006 18:43:13 von Stephan Menzel

hallo,

ich habe etwas mit storedprocedures experimentiert,
und habe eine tabelle wie folgt erstellt!

create table `test` (
`Idx` INT NOT NULL,
PRIMARY KEY (`Idx`))ENGINE=INNODB;

mit folgenden werten!

INSERT INTO `test`(`Idx`)
VALUES (1), (2), (3), (4), (5), (6), (7), (8);

Dann folgende Prozedur:

DROP PROCEDURE IF EXISTS `test`.`test_proc1` $$

CREATE PROCEDURE `test`.`test_proc1`(IN mtxt_Text MEDIUMTEXT)
BEGIN

SELECT `ReIdx` FROM `test`.`test` WHERE (`test`.`Idx` IN
(mtxt_Text));

END $$

wenn ich jetzt den SELECT einfach im QueryBrowser ausführe und für
mtxt_Text z.B. 1,4 einsetze erhalte ich 2 Datensätze!
Führe ich dagegen die Prozedur aus mit
CALL test_proc1('1,4'); aus, erhalte ich immer nur einen datensatz,
egal wie viele Werte nacheinander stehen!
Es ist immer der von dem die Nummer am anfang des übergebenen Wertes
steht!
z.B. CALL test_proc1('1,4'); -> 1
CALL test_proc1('3,2'); -> 3
CALL test_proc1('5,7'); -> 5

kann mir da jemand einen Tip geben, woran das Liegt?

die MYSQL Server version ist 5.0.24 auf einem Win2000 Prof Pc!


cu Stephan

Re: Seltsames Problem mit Storedprocedure

am 11.08.2006 18:45:44 von Stephan Menzel

nochmal Hallo,

die Prozedur sieht so aus, kleiner schreibfehler!:

CREATE PROCEDURE `test`.`test_proc1`(IN mtxt_Text MEDIUMTEXT)
BEGIN

SELECT `Idx` FROM `test`.`test` WHERE (`test`.`Idx` IN
(mtxt_Text));

END $$


cu Stephan

Re: Seltsames Problem mit Storedprocedure

am 12.08.2006 18:48:21 von Thomas Rachel

Stephan Menzel wrote:

> CREATE PROCEDURE `test`.`test_proc1`(IN mtxt_Text MEDIUMTEXT)
> BEGIN
>
> SELECT `ReIdx` FROM `test`.`test` WHERE (`test`.`Idx` IN
> (mtxt_Text));
>
> END $$

Wenn ich das richtig verstehe (ich deduziere jetzt mal aus anderen
Programmiersprachen, da ich mich mit Stored Procedures nicht auskenne,
dann...

> Führe ich dagegen die Prozedur aus mit
> CALL test_proc1('1,4'); aus, erhalte ich immer nur einen datensatz,
> egal wie viele Werte nacheinander stehen!

.... führst Du damit implizit folgenden Query aus:

> Es ist immer der von dem die Nummer am anfang des übergebenen Wertes
> steht!
> z.B. CALL test_proc1('1,4'); -> 1

.... WHERE (test.Idx IN ('1,4')) anstelle von ... IN (1,4)


> CALL test_proc1('3,2'); -> 3

.... WHERE (test.Idx IN ('3,2')) anstelle von ... IN (3,2)

> CALL test_proc1('5,7'); -> 5

.... WHERE (test.Idx IN ('5,7')) anstelle von ... IN (5,7)

da Du ja den Parameter mit '' versiehst, und somit in einen String
verwandelst.


Ob es bei SP die Möglichkeit variabler Parameterlisten gibt, weiß ich
nicht - aber wenn es sich, wie in Deinem Beispiel, immer um 2 Werte
handelt, dann könntest Du diese beiden übergeben und dann in der SP den
Query ... WHERE (test.IDX IN (Param1, Param2)) ausführen lassen.

HTH,


Thomas
--
Ich kenne keinen Adrenalin-Schock, der so zuschlägt, wie der, wenn man
Sachen löscht, die man eigentlich nicht löschen wollte ... Zuckungen
durch den ganzen Körper, erst verkrampft sich der Magen, dann wird es
flau, Hitze- und Kältewallungen ... [Bettina Fink in dasr]

Re: Seltsames Problem mit Storedprocedure

am 13.08.2006 12:52:32 von Stephan Menzel

Hallo,

>Stephan Menzel wrote:
>
>> CREATE PROCEDURE `test`.`test_proc1`(IN mtxt_Text MEDIUMTEXT)
>> BEGIN
>>
>> SELECT `ReIdx` FROM `test`.`test` WHERE (`test`.`Idx` IN
>> (mtxt_Text));
>>
>> END $$
>
>Wenn ich das richtig verstehe (ich deduziere jetzt mal aus anderen
>Programmiersprachen, da ich mich mit Stored Procedures nicht auskenne,
>dann...
>
>> Führe ich dagegen die Prozedur aus mit
>> CALL test_proc1('1,4'); aus, erhalte ich immer nur einen datensatz,
>> egal wie viele Werte nacheinander stehen!
>
>... führst Du damit implizit folgenden Query aus:
>
>> Es ist immer der von dem die Nummer am anfang des übergebenen Wertes
>> steht!
>> z.B. CALL test_proc1('1,4'); -> 1
>
>... WHERE (test.Idx IN ('1,4')) anstelle von ... IN (1,4)
ja das hatte ich mir auch schon überlegt und habe es mal in dem
MySql Command Line Client so getestet:
set @test='2, 5';

SELECT `Idx` FROM `test` WHERE `Idx` IN (@test);

+-----+
| Idx |
+-----+
| 2|
+-----+
1 row in set (0.00 sec)


wobei das gleiche problem auftrat!

>
>
>> CALL test_proc1('3,2'); -> 3
>
>... WHERE (test.Idx IN ('3,2')) anstelle von ... IN (3,2)
>
>> CALL test_proc1('5,7'); -> 5
>
>... WHERE (test.Idx IN ('5,7')) anstelle von ... IN (5,7)
>
>da Du ja den Parameter mit '' versiehst, und somit in einen String
>verwandelst.
>
>
>Ob es bei SP die Möglichkeit variabler Parameterlisten gibt, weiß ich
>nicht - aber wenn es sich, wie in Deinem Beispiel, immer um 2 Werte
>handelt, dann könntest Du diese beiden übergeben und dann in der SP den
>Query ... WHERE (test.IDX IN (Param1, Param2)) ausführen lassen.
>
Es sind nicht nur 2 Parameter, das hatte ich nur so angegeben um das
Problem zu erklären! Es sollte schon so etwas wie eine Parameterliste
sein da es auch mal 20 werte sein könnten!

Kennt jemand für das Problem eine Lösong?


cu Stephan

Re: Seltsames Problem mit Storedprocedure

am 13.08.2006 14:02:12 von thborsdorf

Hallo Stephan!

Stephan Menzel schrieb am 13.08.2006 12:52:
> ja das hatte ich mir auch schon überlegt und habe es mal in dem
> MySql Command Line Client so getestet:
> set @test='2, 5';
> SELECT `Idx` FROM `test` WHERE `Idx` IN (@test);
> wobei das gleiche problem auftrat!

Ich glaube du hast Thomas nicht ganz verstanden, oder?

Es ist ein GROSSER Unterschied ob du "WHERE Idx IN ('2, 5')" schreibst
oder "WHERE Idx IN ('2', '5')" oder gar "WHERE Idx IN (2, 5)"! Thomas
hatte als Lösung die dritte Möglichkeit genannt, du hast aber als
Antwort darauf wieder die erste, von dir bereits als falsch zur
Diskussion gestellte Lösung beschrieben! Deine Lösung würde nur
Datensätze finden, die als Idx exakt den String "2, 5" enthalten, nicht
aber entweder "2" oder "5", mal abgesehen davon daß Idx ein numerisches
Feld ist und keine Strings enthalten kann!

Sprich: Du darfst @test nicht mit einem String, der zwei Ziffern
enthält, füllen sondern mit einer Liste bestehend aus zwei
Integer-Werten. Also quasi so:
set @test = [2, 5];

> Es sind nicht nur 2 Parameter, das hatte ich nur so angegeben um das
> Problem zu erklären! Es sollte schon so etwas wie eine Parameterliste
> sein da es auch mal 20 werte sein könnten!

Die Liste kannst du ja beliebig erweitern:
set @test = [2, 5, ...];

Ich hoffe das war jetzt klar genug!

> cu Stephan

MfG Thomas.

Re: Seltsames Problem mit Storedprocedure

am 13.08.2006 14:29:42 von Stephan Menzel

Hallo,

>> ja das hatte ich mir auch schon überlegt und habe es mal in dem
>> MySql Command Line Client so getestet:
>> set @test='2, 5';
>> SELECT `Idx` FROM `test` WHERE `Idx` IN (@test);
> > wobei das gleiche problem auftrat!
>
>Ich glaube du hast Thomas nicht ganz verstanden, oder?
Ich habe Thomas schon verstanden, nur Du mich nicht!
Das Beispiel als ich es im Command Line Client testete, sollte nur die
Aussage von Thomas unterstreichen, das es daran liegt!

>
>Es ist ein GROSSER Unterschied ob du "WHERE Idx IN ('2, 5')" schreibst
>oder "WHERE Idx IN ('2', '5')" oder gar "WHERE Idx IN (2, 5)"! Thomas
>hatte als Lösung die dritte Möglichkeit genannt, du hast aber als
>Antwort darauf wieder die erste, von dir bereits als falsch zur
>Diskussion gestellte Lösung beschrieben! Deine Lösung würde nur
>Datensätze finden, die als Idx exakt den String "2, 5" enthalten, nicht
>aber entweder "2" oder "5", mal abgesehen davon daß Idx ein numerisches
>Feld ist und keine Strings enthalten kann!
>
>Sprich: Du darfst @test nicht mit einem String, der zwei Ziffern
>enthält, füllen sondern mit einer Liste bestehend aus zwei
>Integer-Werten. Also quasi so:
>set @test = [2, 5];
>
>> Es sind nicht nur 2 Parameter, das hatte ich nur so angegeben um das
>> Problem zu erklären! Es sollte schon so etwas wie eine Parameterliste
>> sein da es auch mal 20 werte sein könnten!
>
>Die Liste kannst du ja beliebig erweitern:
>set @test = [2, 5, ...];
>
>Ich hoffe das war jetzt klar genug!
Klar ist das klar, nur hast du schon mal das:
set @test = [2, 5];
in MySql probiert, wenn du es so selbsverständlich angibst?
Bei mir geht das nicht, zumal es nach meinem Wissen auch nicht gehen
kann, da man einer Variablen keine liste übergeben kann!


cu Stephan

Re: Seltsames Problem mit Storedprocedure

am 13.08.2006 15:05:16 von Christian Kirsch

Stephan Menzel schrieb:
> hallo,
>
> ich habe etwas mit storedprocedures experimentiert,
> und habe eine tabelle wie folgt erstellt!
>
> create table `test` (
> `Idx` INT NOT NULL,
> PRIMARY KEY (`Idx`))ENGINE=INNODB;
>
> mit folgenden werten!
>
> INSERT INTO `test`(`Idx`)
> VALUES (1), (2), (3), (4), (5), (6), (7), (8);
>
> Dann folgende Prozedur:
>
> DROP PROCEDURE IF EXISTS `test`.`test_proc1` $$
>
> CREATE PROCEDURE `test`.`test_proc1`(IN mtxt_Text MEDIUMTEXT)
> BEGIN
>
> SELECT `ReIdx` FROM `test`.`test` WHERE (`test`.`Idx` IN
> (mtxt_Text));
>

Was Du willst: MySQL soll einen String in einer Query evaluieren. Das
geht nicht so einfach. Möglicherweise funktioniert das, wenn Du in
Deiner Stored Procedure ein Prepared Statement erzeugst - das nämlich
*ist* ein String, den Du zur Evaluierung an MySQL übergibst.
Du könntest mal auf planetmysql.org ein bisschen stöbern, ich glaube
mich zu erinnern, dass es da mal ähnliches gab.

Re: Seltsames Problem mit Storedprocedure

am 13.08.2006 15:07:39 von thborsdorf

Hallo Stephan!

Stephan Menzel schrieb am 13.08.2006 14:29:
> Klar ist das klar, nur hast du schon mal das:
> set @test = [2, 5];
> in MySql probiert, wenn du es so selbsverständlich angibst?

Nein, hab ich nicht. Deshalb hab ich "quasi" geschrieben.
Ich könnte mir aber vorstellen daß die Notation so lautet, denn so
deklariert man Listen/Arrays in den meissten mir bekannten
Programmiersprachen.
Ich werd mich aber mal schlau machen!

BTW: Dein Beispiel "create procedure..." funktioniert bei mir auch nicht!

> Bei mir geht das nicht, zumal es nach meinem Wissen auch nicht gehen
> kann, da man einer Variablen keine liste übergeben kann!

Also grundsätzlich kann eine Variable eine Array-Struktur haben, denn
genau das ist es was ich beschrieben habe und was du brauchst. Ob MySQL
das kann weiß ich nicht, ich denke aber ja, denn derartige Anwendungen
werden nicht gerade selten sein.

> cu Stephan

MfG Thomas.

Re: Seltsames Problem mit Storedprocedure

am 13.08.2006 16:37:17 von Stephan Menzel

Hallo,
>Hallo Stephan!
>
>Stephan Menzel schrieb am 13.08.2006 14:29:
>> Klar ist das klar, nur hast du schon mal das:
>> set @test = [2, 5];
>> in MySql probiert, wenn du es so selbsverständlich angibst?
>
>Nein, hab ich nicht. Deshalb hab ich "quasi" geschrieben.
ach so!

>Ich könnte mir aber vorstellen daß die Notation so lautet, denn so
>deklariert man Listen/Arrays in den meissten mir bekannten
>Programmiersprachen.
>Ich werd mich aber mal schlau machen!
wenn ich set @test=(2, 5) schreibe, sagt mir mysql das nur ein
datensatz übergeben werden darf!

>
>BTW: Dein Beispiel "create procedure..." funktioniert bei mir auch nicht!
das liegt vielleicht am delimiter
ich schreib die Prozeduren immer in ein Textdatei und lade diese dann!
im Command Line Client

source LW:/Verzeichniss/textdatei.sql

DELIMITER $$

DROP PROCEDURE IF EXISTS `test`.`test_proc1` $$

CREATE PROCEDURE `test`.`test_proc1`(IN mtxt_Text MEDIUMTEXT)
BEGIN

SELECT `Idx` FROM `test`.`test` WHERE `Idx` IN (mtxt_Text);

END $$

DELIMITER ;

ganz wichtig, das nach dem Semikolon kein Zeilenumbruch mehr erfolgt!

>
>> Bei mir geht das nicht, zumal es nach meinem Wissen auch nicht gehen
>> kann, da man einer Variablen keine liste übergeben kann!
>
>Also grundsätzlich kann eine Variable eine Array-Struktur haben, denn
>genau das ist es was ich beschrieben habe und was du brauchst. Ob MySQL
>das kann weiß ich nicht, ich denke aber ja, denn derartige Anwendungen
>werden nicht gerade selten sein.
>

cu Stephan

Re: Seltsames Problem mit Storedprocedure

am 13.08.2006 16:42:46 von Stephan Menzel

Hallo,

>
>Was Du willst: MySQL soll einen String in einer Query evaluieren. Das
>geht nicht so einfach. Möglicherweise funktioniert das, wenn Du in
>Deiner Stored Procedure ein Prepared Statement erzeugst - das nämlich
>*ist* ein String, den Du zur Evaluierung an MySQL übergibst.
>Du könntest mal auf planetmysql.org ein bisschen stöbern, ich glaube
>mich zu erinnern, dass es da mal ähnliches gab.

Hm das scheint eine Möglichkeit zu sein!
Kann man die EXECUT anweisung auch so schreiben, das sie nichts zurück
gibt, so was ähnliches wie mit DO Syntax?
Denn ich Rufe die Prozedur auch aus einer Funktion heraus auf und da
beschwert sich die Function beim aufrufen von EXECUTE in der
Prozedur!


cu Stephan

Re: Seltsames Problem mit Storedprocedure

am 13.08.2006 17:13:16 von Christian Kirsch

Stephan Menzel schrieb:
> Hallo,
>
>> Was Du willst: MySQL soll einen String in einer Query evaluieren. Das
>> geht nicht so einfach. Möglicherweise funktioniert das, wenn Du in
>> Deiner Stored Procedure ein Prepared Statement erzeugst - das nämlich
>> *ist* ein String, den Du zur Evaluierung an MySQL übergibst.
>> Du könntest mal auf planetmysql.org ein bisschen stöbern, ich glaube
>> mich zu erinnern, dass es da mal ähnliches gab.
>
> Hm das scheint eine Möglichkeit zu sein!
> Kann man die EXECUT anweisung auch so schreiben, das sie nichts zurück
> gibt, so was ähnliches wie mit DO Syntax?
> Denn ich Rufe die Prozedur auch aus einer Funktion heraus auf und da
> beschwert sich die Function beim aufrufen von EXECUTE in der
> Prozedur

Keine Ahnung. Es gibt eine Dokumentation zu MySQL, die sollte solche
Fragen beantworten (dev.mysql.com/doc). Außerdem verkauft O'Reilly ein
Buch, das sich ausschließlich mit Stored Procedures in MySQL beschäftigt ...

Re: Seltsames Problem mit Storedprocedure

am 13.08.2006 17:16:37 von Christian Kirsch

Borsdorf, Thomas schrieb:
> Hallo Stephan!
>
> Stephan Menzel schrieb am 13.08.2006 14:29:
>> Klar ist das klar, nur hast du schon mal das:
>> set @test = [2, 5];
>> in MySql probiert, wenn du es so selbsverständlich angibst?
>
> Nein, hab ich nicht. Deshalb hab ich "quasi" geschrieben.
> Ich könnte mir aber vorstellen daß die Notation so lautet, denn so
> deklariert man Listen/Arrays in den meissten mir bekannten
> Programmiersprachen.

SQL ist keine Programmiersprache. Und dass MySQL keine Array kennt,
dürfte auch hinlänglich bekannt sein.

>
> Also grundsätzlich kann eine Variable eine Array-Struktur haben, denn

Von welcher Art von "Grundsatz" redest Du hier? Du meinst, weil es n
Programmiersprachen gibt, die Array-Typen kennen, müsste dass in der
n+1., die übrigens eben *keine* Programmiersprache ist, auch so sein?
Dann fang' mal an, nach Kontrollstrukturen wie "WHILE" in SQL zu suchen
oder nach Unterprogrammen oder nach Strukturen ...

Analogien sind ja ganz hübsch, aber sie tragen halt nicht beliebig weit.


> genau das ist es was ich beschrieben habe und was du brauchst. Ob MySQL
> das kann weiß ich nicht, ich denke aber ja, denn derartige Anwendungen
> werden nicht gerade selten sein.

Naja, früher hat man sowas in Embedded SQL getrieben. Das kann man heute
auch noch tun. Aber das ist offenbar nicht das, was der OP möchte.