MySql Tárolt eljárás, cursor, ciklus
2021-06-04T11:48:15+02:00
2021-06-05T16:36:06+02:00
2022-08-19T02:22:06+02:00
GZolee79
Sziasztok!

Sajnos nem boldogulok az alábbi feladattal:

Szeretnék írni egy tárolt eljárást (függvényt), ami egy több dimenziós JSON-t ad vissza.
Ehhez létrehoztam egy cursort, de nem sikerült soronkén bejárni a cursor tartalmát.
Hiába kerestem a megoldást, valahol mindig elhasal a kód...

BEGIN DECLARE names_json JSON; DECLARE id INT; DECLARE Name VARCHAR(100); DECLARE names_curs CURSOR FOR SELECT foglalo_id, szamlazasi_nev FROM foglalas_tb WHERE szamlazasi_nev LIKE CONCAT('%', nevreszlet, '%') GROUP BY szamlazasi_nev ORDER BY szamlazasi_nev; OPEN names_curs; FETCH names_curs INTO id, Name; SET names_json = (SELECT JSON_OBJECT("ID", id, "name", Name )); /*SET names_json = JSON_MERGE(names_json, @names);*/ RETURN (names_json); END
A kommentelt rész működne, ha minden ciklusban létre tudnám hozni, a @names változót...

Előre is köszönöm a válaszokat!
Üdv:
Z.
Mutasd a teljes hozzászólást!
A cursor bejárása:

BEGIN DECLARE names_json JSON; DECLARE id INT; DECLARE Name VARCHAR(100); DECLARE done INT DEFAULT 0; DECLARE names_curs CURSOR FOR SELECT ...; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN names_curs; iterationBlock:LOOP FETCH names_curs INTO id, Name; IF done=1 THEN LEAVE iterationBlock; ELSE // a kurzor aktuális értékeinek feldolgozása END IF; END LOOP iterationBlock; CLOSE names_curs; END
Mutasd a teljes hozzászólást!

  • Köszi!

    A bejárás már működik! 

    Tudom, hogy téma fő kérdése a bejárásra vonatkozik, de azt esetleg nem tudod, hogy kell, olyan JSON-t kreálni, aminek elemei is JSON-ok? 

    Vagyis azt szeretném, hogy a CURSOR minden sorát beletenni egy JSON-ba.
    Iz a kód:

    BEGIN DECLARE names_json JSON; DECLARE names_array JSON; DECLARE done TINYINT DEFAULT FALSE; DECLARE id INT; DECLARE Name VARCHAR(100); DECLARE names_curs CURSOR FOR SELECT foglalo_id, szamlazasi_nev FROM foglalas_tb WHERE szamlazasi_nev LIKE CONCAT('%', nevreszlet, '%') GROUP BY szamlazasi_nev ORDER BY szamlazasi_nev; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; SET names_array = (SELECT JSON_OBJECT()); /*Ha ezt nem írom ide akkor NULL lesz az eredmény*/ OPEN names_curs; my_Loop: LOOP FETCH NEXT FROM names_curs INTO id, Name; SET names_json = (SELECT JSON_OBJECT("ID", id, "name", Name )); SET names_array = JSON_MERGE(names_array, names_json); IF done THEN LEAVE my_loop; END IF; END LOOP; CLOSE names_curs; RETURN (names_array); END
    Erre ez az eredmény a phpmyadminban:
    {"ID": [8, 8], "name": ["Teszt Robi", "Teszt Robi"]}
    Nem tudom miért hozza kétszer a 8-ast, meg a Teszt Robit, amikor a Cursorban csak egyszer szerepel...
    Továbbá szerintem a több dimenziós JSON nem így kellene kinézni, úgyhogy valószínű ez a JSON_MERGE nem lesz jó :)

    Azt sem értem, hogy miért kell ez a sor:
    SET names_array = (SELECT JSON_OBJECT());
    Mutasd a teljes hozzászólást!
  • Hali!

    Írd le pontosan, hogy miből (milyen bemenetből, lekérdezésből) mit (milyen kimenetet) szeretnél, mert az a gyanúm, hogy – hasonlóan a korábbi témádhoz – nem kell ide se tárolt eljárás, se kurzor. Szimpla lekérdezéssel megoldható. Persze, elképzelhető, hogy tévedek.

    Mutasd a teljes hozzászólást!
  • Hali!

    Szóval van egy foglalás tábla amiben a foglalók nevére keresek, úgy, hogy beírok egy részletet a nevéből és akinek a nevében szerepel az a részlet azt összegyűjti egy JSON file-ba (Meg ugye ugyazzal a névvel többen is létezhetnek :) )
    Azt szeretném, Ha a json ban így nézne ki egy record [user_id, user_name]
    Lehet ehhez nem is kell több dimenziós JSON tömb...

    Először én sem akartam tárolt eljárást írni. Simán PHP-ben akartam megoldani. Ott nem is lett volna gond ha az ékezetes karaktereket jól kezeli.
    Viszont ha kipróbáltam, akkor mondjuk egy ékezetes névvel amit tuti volt az adatbázisban, (Pl. Mező József) Akkor ha azt írtam, be, hogy , akkor nem talált semmit, ha azt, hogy , akkor megtalálta, zo-ra megint nem.
    Viszont a phpmyadminban működött...
    Ráadásul a saját szerveren működik, de ahová fel kell töltenem, ott nem

    Ezért gondoltam, hogy megírom inkább tárolt eljárásban.

    Mondjuk ha nem kell tárolt eljárásra, akkor is nagyon kíváncsi vagyok a megoldásra.
    Máskor még jól jöhet...
    Mutasd a teljes hozzászólást!
  • Hali!

    Azt szeretném, Ha a json ban így nézne ki egy record [user_id, user_name]

    Ha soronként JSON-objektumot szeretnél kapni:
    SELECT JSON_OBJECT('id', `foglalo_id`, 'nev', `szamlazasi_nev`) AS `json` FROM `foglalas_tb` WHERE `szamlazasi_nev` LIKE CONCAT('%', :nevreszlet, '%') GROUP BY `szamlazasi_nev`
    Megjegyzés: ha ugyanazon feltétel szerint szeretnéd rendezni az eredményhalmazt, mint ami alapján csoportosítasz, akkor nem kell ORDER BY-t megadnod.

    Ha ezekből a JSON-objektumokból egy JSON-tömböt is szeretnél kapni:
    SELECT JSON_ARRAYAGG(JSON_OBJECT('id', `t`.`foglalo_id`, 'nev', `t`.`szamlazasi_nev`)) AS `json` FROM ( SELECT `foglalo_id`, `szamlazasi_nev` FROM `foglalas_tb` WHERE `szamlazasi_nev` LIKE CONCAT('%', :nevreszlet, '%') GROUP BY `szamlazasi_nev` ) AS `t`
    Ha nem ismert a JSON_ARRAYAGG() függvény (mert 10.5.0-s MariaDB-től van – emlékeim szerint neked korábbi verziód van), akkor megoldhatod CONCAT()/GROUP_CONCAT() párossal is:
    SELECT CONCAT( '[', GROUP_CONCAT(JSON_OBJECT('id', `t`.`foglalo_id`, 'nev', `t`.`szamlazasi_nev`) SEPARATOR ','), ']' ) AS `json` FROM ( SELECT `foglalo_id`, `szamlazasi_nev` FROM `foglalas_tb` WHERE `szamlazasi_nev` LIKE CONCAT('%', :nevreszlet, '%') GROUP BY `szamlazasi_nev` ) AS `t`
    Mutasd a teljes hozzászólást!
  • Köszi!

    Már értem! Végre működik :)
    Az a baj nekem eszembe sem jutott, hogy Cursor nélkül próbáljam meg megoldani.

    Mondjuk azt is jó lenne azért tudni, hogy hogyan lehet 2 JSOn objektumot összedadni úgy, hogy egy multidimenziós JSON objektum legyen belőle.
    Mondjuk JSON_ARRAY-al sikerült, csak az volt a baj, hogy az első elemet mindig duplikálta.
    De ez most nem is lényeg. Lezárom a témát.

    Bocsi, ha nem neked adom a pontot, de az eredeti kérdésre a válasz először attitól jött.
    Végül is azzal tudtam bejárni a cursort.

    Legközelebb inkább külön témát nyitok

    Köszi még egyszer!

    Z.
    Mutasd a teljes hozzászólást!
  • Hali!

    Mondjuk azt is jó lenne azért tudni, hogy hogyan lehet 2 JSOn objektumot összedadni úgy, hogy egy multidimenziós JSON objektum legyen belőle.

    Hogy' érted azt, hogy multidimenziós JSON-objektum. Egy (JSON-)objektumnak nincs dimenziója, csak tulajdonságai. Egy olyan (JSON-)tömböt szeretnél, aminek minden eleme egy (JSON-)objektum? Mert erre adtam megoldást. Vagy egy olyan (JSON-)objektumot szeretnél, aminek minden tulajdonsága egy – szimpla – tömb? Mert ez is megoldható.

    Bocsi, ha nem neked adom a pontot, de az eredeti kérdésre a válasz először attitól jött.

    Semmi gond!

    Végül is azzal tudtam bejárni a cursort.

    Ez a lényeg! Mondjuk, továbbra sem értem, hogy mi szükség itt tárolt eljárásra, kurzorra.

    Legközelebb inkább külön témát nyitok

    Ugyan fontos az is, hogy mivel/hogyan próbálkozol egy probléma megoldása során, de legközelebb azt is írd majd le – pontosan (!) –, hogy mit is szeretnél. Mert nagyon könnyen előfordulhat, hogy a cél eléréséhez nem feltétlenül az a legoptimálisabb/-hatékonyabb/-gyorsabb/stb. út, amin próbálkozol.

    Mutasd a teljes hozzászólást!
  • Hali!

    Hogy' érted azt, hogy multidimenziós JSON-objektum. Egy (JSON-)objektumnak nincs dimenziója, csak tulajdonságai. Egy olyan (JSON-)tömböt szeretnél, aminek minden eleme egy (JSON-)objektum? Mert erre adtam megoldást. Vagy egy olyan (JSON-)objektumot szeretnél, aminek minden tulajdonsága egy – szimpla – tömb? Mert ez is megoldható.

    Szóval arra gondoltmam, hogy van 2 JSON_OBJECTEM.
    json1{"id", 0, "nev", "Teszt Elek"}
    json2{"id", 1, "nev", "Teszt Róbert"}

    Ha összeadom (json1+json2) akkor ezt kapjam:

    [{"id": 0, "nev": "Teszt Elek"},{"id": 1, "nev": "Teszt Róbert"}]

    Vagyis pont azt amit a te kódod készít!
    Így akartam megcsinálni, de sehogy sem működött amikor ciklusbólm akartam: 

    SET result_json = JSON_ARRAY(result_json, names_json1);
    Viszont ha előtte beállítottam, hogy:

    SET json1 = (SELECT JSON_OBJECT("id", 0, "nev", "Teszt Elek")); SET json1 = (SELECT JSON_OBJECT("id", 1, "nev", "Teszt Róbert")); SET result_json = JSON_ARRAY(json1, json2);
    Akkor jó lett. Azzal kínlódtam egy napot, hogy ezt összehozzam.
    Ciklusból nem sikrült, de a te megoldásod jó!

    Ez a lényeg! Mondjuk, továbbra sem értem, hogy mi szükség itt tárolt eljárásra, kurzorra.

    Hát mint írtam az ékezetes karakterek keresése miatt. hiába kínlódtam vele, simán PHP-ből nem találta meg mondjuk az " betűs neveket. De ha phpmyadminból próbáltam futtatni akkor viszont igen.
    Ezért kezdtem bele egyálltalán a tárolt eljárás csinálni neki. Első verzió simán csak PHP volt...
    Mondjuk most sem az igazi, mert van valaki Mező névvel.
    Ha az egyik szerveren (ez a saját) keresem így (), simán megtalálja, viszont ha a másikon (ezen fut konkrétan a program) akkor azt írja, ki, hogy null.
    Ugyanaz a kód, ugyanaz a név és mégsem találja...
    Úgyhogy ezen még mindig agyalok...

    Ugyan fontos az is, hogy mivel/hogyan próbálkozol egy probléma megoldása során, de legközelebb azt is írd majd le – pontosan (!) –, hogy mit is szeretnél. Mert nagyon könnyen előfordulhat, hogy a cél eléréséhez nem feltétlenül az a legoptimálisabb/-hatékonyabb/-gyorsabb/stb. út, amin próbálkozol. 

    Rendben, legközelebb azzal kezdtem, hogy mit szeretnék megoldani. Csak azt sem akartam, hogy jöjjöne le a kérdés, hogy meg sem próbáltam megoldani.
    Mutasd a teljes hozzászólást!
abcd