[MySQL] - IN parameter string -> set (array) in Stored Proc.

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • gvanh
  • Registratie: April 2003
  • Laatst online: 02-12-2023

gvanh

Webdeveloper

Topicstarter
Goedemiddag,

In een stored procedure in MySQL wil ik graag een SET van ids meegeven waarop kan worden gecontroleerd binnen de stored procedure, dus zoiets als in volgende (onzin)voorbeeld:

MySQL:
1
2
3
4
5
6
7
CREATE PROCEDURE getCars(colorIds TEXT)
BEGIN
DECLARE cur1 CURSOR FOR 
        SELECT  * FROM cars WHERE colorID IN (colorIds);
END

CALL getCars('17, 28, 93');


Maarrr ... de gegeven TEXT wordt niet gezien als SET van ids. Daardoor wordt wel het eerstgegeven ID gematched, maar de IDs daarna worden genegeerd. Is er een mogelijkheid om de TEXT parameter om te zetten naar een SET (ARRAY)?

Ik heb al iets geprobeerd als:
MySQL:
1
REPLACE(colorIds, "'", "")


Maar dat maakt niet uit. Waarschijnlijk omdat de gegeven string al helemaal geen quotes bevat.

Alvast veel dank voor de hulp.

[ Voor 12% gewijzigd door gvanh op 18-09-2009 16:15 ]


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Zomaar een wilde gok/poging:

code:
1
CALL getCars("'17, 28, 93'");

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Volgens mij beschrijft de eerste hit al meteen een werkbare oplossing. Of het een mooie oplossing is is een tweede; SP's en arrays zijn nou eenmaal ellende (ook onder MSSQL, hoewel dat tegenwoordig wel beter is geloof ik sinds MSSQL 2005>)

Overigens staat 't ook in de FAQ van MySQL 5

[ Voor 17% gewijzigd door RobIII op 18-09-2009 18:10 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • gvanh
  • Registratie: April 2003
  • Laatst online: 02-12-2023

gvanh

Webdeveloper

Topicstarter
Ja, de geopperde oplossingen daar maken de stored procedure wel tig keer ingewikkelder.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
gvanh schreef op vrijdag 18 september 2009 @ 19:10:
Ja, de geopperde oplossingen daar maken de stored procedure wel tig keer ingewikkelder.
Het is dat of stikken. Simpel ;)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • gvanh
  • Registratie: April 2003
  • Laatst online: 02-12-2023

gvanh

Webdeveloper

Topicstarter
Maar is het dan mogelijk om het resultaat van een andere stored procedure te gebruiken als SET voor de eerste stored procedure?

Dus zoiets als (pseudo-code)":
MySQL:
1
2
3
4
5
6
7
8
STORED PROCEDURE `explode`(IN STRING ids) {
  /* insert ids in temp table */
  SELECT * FROM temp table;
}

STORED PROCEDURE `getCars`(IN STRING colorIds) {
  SELECT * FROM `cars` WHERE colorID IN ( explode(colorIds) );
}


Of is zo'n constructie ook geen mogelijkheid omdat de `explode` stored procedure geen return value geeft?

Acties:
  • 0 Henk 'm!

  • DamadmOO
  • Registratie: Maart 2005
  • Laatst online: 14-09 10:22
RobIII schreef op vrijdag 18 september 2009 @ 18:04:
Volgens mij beschrijft de eerste hit al meteen een werkbare oplossing. Of het een mooie oplossing is is een tweede; SP's en arrays zijn nou eenmaal ellende (ook onder MSSQL, hoewel dat tegenwoordig wel beter is geloof ik sinds MSSQL 2005>)
Onder MSSQL valt het ook allemaal wel mee, het enige wat je nodig hebt is een tabular function.

SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ALTER FUNCTION [dbo].[fnSplit](
    @String NVARCHAR(max)
    ,@Delimiter NVARCHAR(10)
)
RETURNS @Values TABLE (Value NVARCHAR(100))
AS
BEGIN
    DECLARE @i INT, @Length INT, @Lasti INT;
    IF(@String NOT LIKE N'%' + @Delimiter)
        SET @String = @String + @Delimiter;
    SET @Lasti = 1;
    SET @i = CHARINDEX(@Delimiter, @String, 2);
    WHILE(@i > 0)
        BEGIN
            INSERT @Values VALUES (LTRIM(RTRIM(SUBSTRING(@String, @Lasti, @i - @Lasti))));
            SET @Lasti = @i + LEN(@Delimiter);
            SET @i = CHARINDEX(@Delimiter, @String, @Lasti);
        END
    RETURN;
END


en die gebruik je dan gewoon zo:
SQL:
1
2
3
SELECT *
FROM Table
WHERE Iets IN (SELECT a.Value FROM dbo.fnSplit(N'test,test2,test3', N',') AS a)


Of je doet er iets mee in een join of iets dergelijks.

Of dit in MySQL werkt weet ik niet, daar maak ik al jaren geen gebriuk meer van >:)

Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Offtopic en ter informatie: In PostgreSQL kun je een variabel aantal parameters opgeven in een functie maar ook een array (datatype). Beide oplossingen zijn voor bovenstaand probleem echt ideaal, is zeer eenvoudig op te lossen.

  • gvanh
  • Registratie: April 2003
  • Laatst online: 02-12-2023

gvanh

Webdeveloper

Topicstarter
Even voor het nageslacht:

Ons specifieke probleem hebben we uiteindelijk vrij eenvoudig kunnen oplossen met de native MySQL functie FIND_IN_SET, die je een string van comma-seperated strings kunt meegeven als argument, evenals het id waarop je wil zoeken. En voila ... het gewenste resultaat.

Dus blijkbaar toch de geopperde ingewikkelde methodes niet nodig.

Maar dank voor het meedenken!
Pagina: 1