Fb-SP:SELECT WHERE-be IN utáni valtozó paraméter

Fb-SP:SELECT WHERE-be IN utáni valtozó paraméter
2007-07-20T15:00:19+02:00
2007-07-23T14:27:18+02:00
2022-11-05T07:45:37+01:00
KarIst
FireBird-ben egy tárolt eljárásnak átadok az egyik paraméterben egy karkatersort (pl.: '1,4,7'), amit az eljárásban levő select-ben található where feltétel IN (...) részében szeretnék megadni.
Pl.:
CREATE PROCEDURE PROC_SP(ERTEKEK VARCHAR(40))
(...)
SELECT x, y, z FROM T WHERE x IN (:ertekek)
(...)

Ilyenkor sajnos 1 értéknek tekinti az '1,4,7'-et és nem kiértékelten 1,4,7-nek...
Ami logikusnak is tűnhet az ő szempontjából (az enyémből cseppet sem), nos akkor az ilyen típusú lekérdezést hogyan valósítsam meg tárolt eljárás felhasználásával. Néztem a CAST()-ot hátha,... de az nem erre való.
Delphi oldalon végig lehet szenvedni egy plusz templit táblával (ennél jóval bonyolultabb az SP, csak az elv miatt 1szerűsíték) stb. de az cseppet sem elegáns és égnek áll a hajam tőle ().
Gondolom van erre vmilyen bevált módszere vkinek, hátha

Köszönöm a segítséget!
Mutasd a teljes hozzászólást!
Hi!

Használj dinamikus SQL-t!
Sajna most nincs lehetőségem kipróbálni, de valami ilyesmi:
CREATE PROCEDURE DYN_TEST(param VARCHAR(255)) RETURNS(DARAB INTEGER) AS DECLARE VARIABLE qry VARCHAR(1000); BEGIN qry='SELECT COUNT(*) FROM TABLA WHERE ID IN (' || :param || ')'; EXECUTE STATEMENT qry INTO :DARAB; END;

Alex
Mutasd a teljes hozzászólást!

  • ha vessző van benne, akkor instring-gel megkeresed a vesszőket, és substringgel kirobbantod a megfelelő karakterláncokat.

    Noémi
    Mutasd a teljes hozzászólást!
  • kicsit pontosítva:

    INSTR (string , substring [, position [, occurrence ] ])

    megadod miben keresel mit hanyadik előfordulásától

    substr: substringeled az 1. attribútumhoz: 1. karaktertől 1. vesszőig,
    2.attr-hoz 1.vesszőtől 2-ig....

    Mutasd a teljes hozzászólást!
  • Nem a legszebb, de :
    SELECT x, y, z FROM T WHERE x IN (:ertek1, :ertek2, ...)

    Vagy Delphi oldalon a paraméterekből csinálsz egy karakterláncot, azt adod át az SP-nek és az SP szedi szét a kapott sztringet és "castolja" ertek1, ertek2-re, stb...
    Mutasd a teljes hozzászólást!
  • köszi a gondolatokat...

    Noémi:
    kirobbantás oké, de azt utána hogyan adom meg az IN () paramétereként; nem beszélve arról hogy n darab érték lehet az ertek-ben

    kardosi:
    ezzel az a baj, hogy n darab ertek lehet, azt pedig nem tudom hogyan lekezelni az SP-ben...
    Mutasd a teljes hozzászólást!
  • hmmmm... igaz

    most nem jut más eszembe, pedig biztos van szebb megoldás is, de:

    ha egy darab bemeneti értékként adod be az eljárásnak értéket:

    szervezheted ciklusba, és úgy szeded ki egyesével változókba... és adod át majd a select-nek. Mivel 40 hosszúra tetted a stringet, ezért nem fog az olyan sokáig tartani...

    Most más nem jut az eszembe
    Mutasd a teljes hozzászólást!
  • Hi!

    Használj dinamikus SQL-t!
    Sajna most nincs lehetőségem kipróbálni, de valami ilyesmi:
    CREATE PROCEDURE DYN_TEST(param VARCHAR(255)) RETURNS(DARAB INTEGER) AS DECLARE VARIABLE qry VARCHAR(1000); BEGIN qry='SELECT COUNT(*) FROM TABLA WHERE ID IN (' || :param || ')'; EXECUTE STATEMENT qry INTO :DARAB; END;

    Alex
    Mutasd a teljes hozzászólást!
  • select x from table where (x in (1,2,3))

    szerintem ennek mukodnie kell ha x szam tipusu
    Mutasd a teljes hozzászólást!
  • Köszi a megoldást! Ezt az EXECUTE STATEMENT dolgot már rég kerestem a FireBird-ben.

    Az igazszághoz hozzátartozik, hogy végül nem ezzel a módszerrel oldottam meg a dolgot, mivel (ahogy a doksi is írja) lassabb és sok benne a hibalehetőség, ami nálam hatványozottan előjött (TIMESTAMP típusú paraméternél hiába CAST()-oltam, akkor is hiba; plusz tipusegyeztetési hiba, pedig mind2 FLOAT volt?).

    Ezért egy másik módszert alkalmaztam: Próbáltam az IN (:parameterek)-t általánosítani, ahol a ()-jelbe egy másik SZETSZED eljárás SELECT-jét tettem:

    SELECT x,y,z FROM T WHERE x IN(SELECT ELEMEK FROM PROC_SZETSZED(:ertekek))

    ahol a SZETSZED eljárás visszaadja a vesszővel elválasztott elemeket sorokba:
    CREATE PROCEDURE SZETSZED( MIT VARCHAR(1000) CHARACTER SET WIN1250) RETURNS( ELEMEK VARCHAR(100) CHARACTER SET WIN1250) AS DECLARE VARIABLE SZODB INTEGER; DECLARE VARIABLE SZOSZAM INTEGER; BEGIN /* Egy karakterláncot szétszed a vesszővel elválasztott részekre */ szodb=0; SZOSZAM=WORDCOUNT(MIT,',',0); WHILE (SZOSZAM>szodb) DO BEGIN szodb=:szodb+1; ELEMEK=WORDNUM(MIT,szodb,',',0); SUSPEND; END END
    Ahol a WORDCOUNT(...) és a WORDNUM(...) fv-ek az rfunc.dll lib-ben levő UDF-ek.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd