Tajszám tagolása SQLite-ban

Szervusztok!

Kezdő adatbázis-bütykölő vagyok, az SQLite-tal birkózom. Ő áll nyerésre.

A tajszámokkal gyűlik meg most a bajom, amik ügye 0-val is kezdődhetnek, így csak azt a lehetőséget találtam, hogy text adattípusban tároljam őket. Namost szeretném elérni, hogy hármasával tagolódjanak a lekérdezésben, mert úgy jobban olvasható.

Van ehhez valamilyen pöpec lekérdezés, ami a formátumot is előírja a SQLite-nak, vagy mivel úgysem fogok vele műveleteket végezni, vigyem inkább úgy be? Bár el tudok olyan szitut képzelni, hogy valaki folyamatosan írva akar keresni.

Vagy eleve rossz adattípussal kezdtem?

Remélem érthetően írtam.

Hozzászólások

Szerkesztve: 2024. 11. 25., h – 22:24

Szerintem szed ki belőle a "-" jeleket tároláskor, illetve kereséskor is szed ki, sőt kizárólag numerikus adatokat engedj be. Így mindegy milyen formátumban írja a keresést úgyis meg fogja találni.

String teljesen jó, nem kell túlgondolni, fontosabb hogy jövőálló legyen.

Ha pedig tényleg SQL-ben akarod darabolni a megjelenítést, akkor egyszerűen:

SELECT SUBSTR(taj, 1, 3) || '-' || SUBSTR(taj, 4, 3) || '-' || SUBSTR(taj, 7, 3) AS tajdarabolt FROM tajtabla;

Avagy csinálhatsz egy view-t:

CREATE VIEW tajdarabolt_view AS
SELECT 
    SUBSTR(taj, 1, 3) || '-' || 
    SUBSTR(taj, 4, 3) || '-' || 
    SUBSTR(taj, 7, 3) AS tajdarabolt
FROM tajtabla;

És akkor ez a view mindig az eredeti tábla adatait mutatja a definiált formátumban.

SELECT * from tajdarabolt_view;

De valóban jobb lenne ezt frontend oldalon kezelni.

A TAJ ugyebár nem szám, hanem számjegyeket tartalmazó string (ahogy az adószám sem szám, meg a személyigazolvány-szám sem szám). Emiatt az adatbázisban sem számként tárold, hanem stringként.

Így is dolgozd fel, és adatbázisban is így tárold.
A formázást pedig ne az adatbázis lekérdezéskor csináld, hanem amikor azt a TAJ-t meg kell valahol jeleníteni, vagy el kell valahova küldeni, akkor a megjelenítés/küldés formátumára konvertáld.

Például lehet, hogy felhasználók felé fontos a hármas tagolás, míg lehet, hogy egy gépi interfészen meg a nyers, tagolás nélküli TAJ kell. Az adatbázisból kiszeded nyersen, és mindenhova úgy írod ki, ahogy ki kell írni.

1, Szám az, amivel matematikai műveletet akarsz végezni, minden más szöveg.

2, Tárold tömören, szigorúan adattisztítva (!), validálva, majd a megjelenítésnél formázod, ahogy csak akarod, különben egy csomó szopást húzol magadra.

Szerkesztve: 2024. 11. 14., cs – 18:02

+1 Amit masok is irtak. Tiszta adat, frontend formazas. Mi a frontend amit hasznalsz? A legtobb webapp cucc ezt siman lekezeli.

Ha mégis számként akarod tárolni, és csak az a baj, hogy kezdődhet 0-val, akkor írj elé egy 1-est, megjelenítéskor meg szedd le! :-)

De tényleg csak vicc volt, mert ahogy fentebb is írták, stringként érdemes tárolni. És ha kellhet külföldi TAJ is, akkor arra is fel kell készülni, hogy annak is legyen hely, és menjen át az ellenőrzésen! Viszont az adattisztítás is jó ötlet: egy dolog egyféleképpen szerepelhessen, hogy később ne legyen ebből probléma!

Szerkesztve: 2024. 11. 14., cs – 23:54

"Bár el tudok olyan szitut képzelni, hogy valaki folyamatosan írva akar keresni."

Amit keresel, az az input normalizálása. A TAJ az 8+1 darab számjelgy karakterből álló string (8 értékes jegy és egy checksum), mivel nem egy legfeljebb 9 jegyű számként használod, így a bevitelnél (rögzítés és keresés egyaránt) a numerikus karaktereken kívül midnent ki kell takarítani az inputból, aminek így egyrészt pontosan 9 karakter hosszúnak kell lennie, _és_ a cheksum-nak is rendben kell lennie.

Házi feladat: a TAJ-számban található checksum pozíciójának és kiszámításának utánanézni.

A TAJ szám egy kilenc számjegyből álló szám, amelyben az első nyolc számjegy egy folyamatosan kiadott egyszerű sorszám, amely mindig az előző, utoljára kiadott sorszámból egy hozzáadásával keletkezik.

A kilencedik számjegy ellenőrző ún. CDV kód, melynek képzési algoritmusa az alábbi:

  • A TAJ szám első nyolc számjegyéből a páratlan (szerk: balról jobbra számolom) helyen állókat hárommal, a páros helyen állókat héttel szorozzuk, és a szorzatokat összeadjuk.
  • Az összeget tízzel elosztva a maradékot tekintjük a kilencedik, azaz CDV kódnak.

forrás: https://github.com/karsany/hunlib4j/issues/4

 

 

Saját TAJ számon ki kellett próbálni. Én megtettem, nekem ment

Szerkesztve: 2024. 11. 26., k – 17:19

Valamikor réges-régen egy messzi... használtam én is a TAJ számot adatbázisban.

Kikerestem, ha csak tanulás miatt is, vagy hogy meglegyen az utókornak, vagy csak úgy, én így használtam:

-- Óvatosan a tábla törlésével, mert a tábla és a tartalma elveszik.
-- DROP TABLE IF EXISTS "taj_tábla";
CREATE TABLE "taj_tábla" (
	"uid"	TEXT(32) NOT NULL UNIQUE,
	"taj"	TEXT(9) NOT NULL UNIQUE,
	PRIMARY KEY("uid")
);

DROP INDEX IF EXISTS "index:user_id_taj";
CREATE INDEX "index:user_id_taj" ON "taj_tábla" (
	"uid",
	"taj"
);

 

A TAJ tárolására és módosítására trigger-eket használtam, így nem kellett külön kódot írni, fordítani, publish, stb. De ez ízlés kérdése. A Bábeli zűrzavart is lehet így kezelni.

Trigger a létrehozáshoz:

DROP TRIGGER IF EXISTS "ellenőrizzük_a_taj_számot_mielőtt_beszúrnánk";
CREATE TRIGGER "ellenőrizzük_a_taj_számot_mielőtt_beszúrnánk"
BEFORE INSERT ON "taj_tábla"
FOR EACH ROW
BEGIN
    SELECT 
        CASE
            WHEN LENGTH(NEW.taj) != 9 THEN
                RAISE(ABORT, 'A TAJ hossza nem megfelelő.')
            WHEN NOT NEW.taj GLOB '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' THEN
                RAISE(ABORT, 'A TAJ csak számjegyeket tartalmazhat.')
            WHEN (
                (
                    (SUBSTR(NEW.taj, 1, 1) * 3) +
                    (SUBSTR(NEW.taj, 2, 1) * 7) +
                    (SUBSTR(NEW.taj, 3, 1) * 3) +
                    (SUBSTR(NEW.taj, 4, 1) * 7) +
                    (SUBSTR(NEW.taj, 5, 1) * 3) +
                    (SUBSTR(NEW.taj, 6, 1) * 7) +
                    (SUBSTR(NEW.taj, 7, 1) * 3) +
                    (SUBSTR(NEW.taj, 8, 1) * 7)
                ) % 10
            ) != CAST(SUBSTR(NEW.taj, 9, 1) AS INTEGER) THEN
                RAISE(ABORT, 'Hibás TAJ szám.')
        END;
END;

Trigger a módosításhoz:

DROP TRIGGER IF EXISTS "ellenőrizzük_a_taj_számot_mielőtt_frissítenénk";
CREATE TRIGGER "ellenőrizzük_a_taj_számot_mielőtt_frissítenénk"
BEFORE UPDATE ON "taj_tábla"
FOR EACH ROW
BEGIN
    SELECT 
        CASE
            WHEN LENGTH(NEW.taj) != 9 THEN
                RAISE(ABORT, 'A TAJ hossza nem megfelelő.')
            WHEN NOT NEW.taj GLOB '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' THEN
                RAISE(ABORT, 'A TAJ csak számjegyeket tartalmazhat.')
            WHEN (
                (
                    (SUBSTR(NEW.taj, 1, 1) * 3) +
                    (SUBSTR(NEW.taj, 2, 1) * 7) +
                    (SUBSTR(NEW.taj, 3, 1) * 3) +
                    (SUBSTR(NEW.taj, 4, 1) * 7) +
                    (SUBSTR(NEW.taj, 5, 1) * 3) +
                    (SUBSTR(NEW.taj, 6, 1) * 7) +
                    (SUBSTR(NEW.taj, 7, 1) * 3) +
                    (SUBSTR(NEW.taj, 8, 1) * 7)
                ) % 10
            ) != CAST(SUBSTR(NEW.taj, 9, 1) AS INTEGER) THEN
                RAISE(ABORT, 'Hibás TAJ szám.')
        END;
END;

 

Fentebb kruska is említette, egy view a lekérdezéshez:

DROP VIEW IF EXISTS "formázott_taj";
CREATE VIEW "formázott_taj" AS
SELECT 
    uid,
    SUBSTR(taj, 1, 3) || '-' || 
    SUBSTR(taj, 4, 3) || '-' || 
    SUBSTR(taj, 7, 3) AS taj
FROM taj_tábla;

 

Ez a két view

  • teszt_uid
  • teszt_taj_szám

a teszteléshez és a unit tesztek miatt készült.

Teszt "uid" generálás:

DROP VIEW IF EXISTS "teszt_uid";
CREATE VIEW "teszt_uid" AS
SELECT lower(hex(randomblob(16))) AS uid;

Valid teszt TAJ szám készítés:

DROP VIEW IF EXISTS "teszt_taj_szám";
CREATE VIEW "teszt_taj_szám" AS
WITH VéletlenSzámok AS (
    SELECT
        ABS(RANDOM() % 10) AS sz1,
        ABS(RANDOM() % 10) AS sz2,
        ABS(RANDOM() % 10) AS sz3,
        ABS(RANDOM() % 10) AS sz4,
        ABS(RANDOM() % 10) AS sz5,
        ABS(RANDOM() % 10) AS sz6,
        ABS(RANDOM() % 10) AS sz7,
        ABS(RANDOM() % 10) AS sz8
),
Checksum AS (
    SELECT 
        sz1, sz2, sz3, sz4, sz5, sz6, sz7, sz8,
        ( (sz1 * 3) + (sz2 * 7) +
          (sz3 * 3) + (sz4 * 7) +
          (sz5 * 3) + (sz6 * 7) +
          (sz7 * 3) + (sz8 * 7)
        ) % 10 AS cdv
    FROM VéletlenSzámok
)
SELECT 
    CAST(sz1 AS TEXT) || CAST(sz2 AS TEXT) || CAST(sz3 AS TEXT) || CAST(sz4 AS TEXT) ||
    CAST(sz5 AS TEXT) || CAST(sz6 AS TEXT) || CAST(sz7 AS TEXT) || CAST(sz8 AS TEXT) ||
    CAST(cdv AS TEXT) AS taj
FROM Checksum;

 

Ez a három view

  • hibás_taj_szám

  • hibás_taj_hossz

  • hibás_taj_tartalom

a trigger-ben található hibaellenőrzésekhez készült.

Hibás TAJ szám:

DROP VIEW IF EXISTS "hibás_taj_szám";
CREATE VIEW "hibás_taj_szám" AS
WITH VéletlenSzámok AS (
    SELECT
        ABS(RANDOM() % 10) AS sz1,
        ABS(RANDOM() % 10) AS sz2,
        ABS(RANDOM() % 10) AS sz3,
        ABS(RANDOM() % 10) AS sz4,
        ABS(RANDOM() % 10) AS sz5,
        ABS(RANDOM() % 10) AS sz6,
        ABS(RANDOM() % 10) AS sz7,
        ABS(RANDOM() % 10) AS sz8
),
Checksum AS (
    SELECT 
        sz1, sz2, sz3, sz4, sz5, sz6, sz7, sz8,
        (( (sz1 * 3) + (sz2 * 7) +
           (sz3 * 3) + (sz4 * 7) +
           (sz5 * 3) + (sz6 * 7) +
           (sz7 * 3) + (sz8 * 7)
        ) % 10 + 1) % 10 AS hibás_cdv
    FROM VéletlenSzámok
)
SELECT 
    CAST(sz1 AS TEXT) || CAST(sz2 AS TEXT) || CAST(sz3 AS TEXT) || CAST(sz4 AS TEXT) ||
    CAST(sz5 AS TEXT) || CAST(sz6 AS TEXT) || CAST(sz7 AS TEXT) || CAST(sz8 AS TEXT) ||
    CAST(hibás_cdv AS TEXT) AS taj
FROM Checksum;

Hibás hosszúságú TAJ szám:

DROP VIEW IF EXISTS "hibás_taj_hossz";
CREATE VIEW "hibás_taj_hossz" AS
WITH VéletlenHossz AS (
    SELECT ABS(RANDOM() % 7) + 6 AS hossz
),
Számjegyek AS (
    SELECT GROUP_CONCAT(ABS(RANDOM() % 10), '') AS taj
    FROM (SELECT 1 AS dummy FROM (SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) LIMIT (SELECT hossz FROM VéletlenHossz))
)
SELECT taj
FROM Számjegyek;

Hibás TAJ tartalom:

DROP VIEW IF EXISTS "hibás_taj_tartalom";
CREATE VIEW "hibás_taj_tartalom" AS
WITH VéletlenKarakterek AS (
    SELECT
        CHAR(ABS(RANDOM() % 26) + 65) AS random_betu,
        CHAR(ABS(RANDOM() % 26) + 97) AS random_kisbetu,
        CHAR(ABS(RANDOM() % 15) + 33) AS random_spec,
        ABS(RANDOM() % 10) AS random_szam
),
KarakterSor AS (
    SELECT GROUP_CONCAT(val, '') AS taj
    FROM (
        SELECT
            CASE
                WHEN RANDOM() % 4 = 0 THEN random_betu
                WHEN RANDOM() % 4 = 1 THEN random_kisbetu
                WHEN RANDOM() % 4 = 2 THEN random_spec
                ELSE CAST(random_szam AS TEXT)
            END AS val
        FROM VéletlenKarakterek, (SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1) LIMIT 9
    )
)
SELECT taj
FROM KarakterSor;

 

Teszt SQL-eke:

sqlite> SELECT uid FROM teszt_uid;
beb6c25c55290015edb217054f82f202

sqlite> SELECT taj FROM teszt_taj_szám;
118337137

sqlite> SELECT taj FROM hibás_taj_szám;
579216812

sqlite> SELECT taj FROM hibás_taj_hossz;
1814710676

sqlite> SELECT taj FROM hibás_taj_tartalom;
5555j5F55

sqlite> INSERT INTO taj_tábla (uid, taj) SELECT uid, taj FROM teszt_uid, hibás_taj_szám;
Runtime error: Hibás TAJ szám. (19)

sqlite> INSERT INTO taj_tábla (uid, taj) SELECT uid, taj FROM teszt_uid, hibás_taj_tartalom;
Runtime error: A TAJ csak számjegyeket tartalmazhat. (19)

sqlite> INSERT INTO taj_tábla (uid, taj) SELECT uid, taj FROM teszt_uid, hibás_taj_hossz;
Runtime error: A TAJ hossza nem megfelelő. (19)

sqlite> INSERT INTO taj_tábla (uid, taj) SELECT uid, taj FROM teszt_uid, teszt_taj_szám;
sqlite> INSERT INTO taj_tábla (uid, taj) SELECT uid, taj FROM teszt_uid, teszt_taj_szám;

sqlite> SELECT * FROM taj_tábla;
1c2bf84307bdba53007233ce9ccd5538|302941289
00cbeb3b6b2a5aaa085ded6ec920c352|128633852

sqlite> SELECT * FROM formázott_taj WHERE uid = '1c2bf84307bdba53007233ce9ccd5538';
1c2bf84307bdba53007233ce9ccd5538|302-941-289