Marek Olšavský

Linux, databáze, astronomie, ham radio (OK1TOL), výletování a tak vůbec

SQLite: emulace RPAD a LPAD

Kategorie:

Štítky:

SQLite je velmi lehké řešení SQL databáze, ne vždy je potřebný „těžkotonážní server“ (PostgreSQL, MariaDB, …), a tak postrádá některou funkčnost. Mírně jsem postrádal ZEROFILL INTEGER, nebo možnost si jej emulovat pomocí funkce LPAD().

Reklamy

Proč?

ZEROFILL potřebuji na řazení. Používám hierarchickou strukturu pro technická data kategorií, ale v rozšířené struktuře mám i atribut visorder, jež určuje pořadí a který si pak funkcí CONCAT_WS() spojuji do dlouhého řadícího řetězce. Řazení podle takto vygenerovaného atributu je lexikografické, takže v řazení stromu s vygenerovanými řetězci ‚00001100002‘ a ‚112‘ by bylo úplně jiné, rozhodně potřebuji za sebou 00000100001, 00000100022, 000002, 00000200001, ale nikoliv 1, 11, 2, 21, 122 (nadřazená je 1 pod níž je 22, nebo je nadřazená 12 a pod ní 2?).

Pravda není to udeální stav, řazení by šlo udělat i podle atributu left a v administraci bych musel pořešit „přeházení leftright na dané úrovni a ve všech podřazených větvích. (A do toho se mi nechce.)

Není to jediné uplatnění, třeba ve mzdovém software používáme osobní čísla a čísla útvarů doplněná zleva nulami na pevnou délku. Avšak mzdy jsou psány nad FirebirdSQL, takže funkce LPAD a RPAD mám k dispozici.

Jak v SQLite?

Dovolím si krátké vysvětlení, jak LPAD funguje. Základní syntaxe je lpad(string text, pozadovana_delka int [, vyplnovy_text text]) (například SELECT LPAD('test', 5, '#'); vrátí #test), pokud se nezadá výplňový text, je použit znak mezery. Ekvivalentně funguje RPAD, jen doplňuje zprava.

Funkci LPAD i RPAD v SQLite programátor nenajde, jde ji však snadno emulovat pomocí funkcí pro práci s řetězci. Zkrátka „malým cimrmanovským úkrokem stranou“.

Workaround funkcí LPAD a RPAD vypadá následovně:

LPAD(sloupec, 10, ‚#‘)
SUBSTR(‚##########‘ || sloupec, -10, 10)
RPAD(sloupec, 10, ‚#‘)
SUBSTR(sloupec || ‚##########‘, 1, 10)

Snad jedinou slabinou je nutnost mít výplňový řetězec celý, tj. v maximální délce, do jaké hodláme doplňovat.

Comments

4 komentáře: „SQLite: emulace RPAD a LPAD“

  1. Ondřej Tůma avatar

    SQLite API má jednu úžasnou vlastnost, lze jím registrovat další funkce, které se pak volají v SQL dotazech. Takže si lze napsat vlastní implementaci vlastně čehokoli. Jedna z věcí, která se takto doslova musí psát, byť je pro to v SQLite rezervované slovo, je regexp 😉

    1. Marek Olšavský avatar

      [Ondřej Tůma] To jsem použil na něco složitějšího (v C#), attachují se po každém připojení. Bohužel mám pocit, že to je dobrý nápad v programu, kde je připojení perzistentní po dobu běhu aplikace (řádově minuty, hodiny), ne v něčem tak krátkodobém, jako je script generující web stránku.

      1. Ondřej Tůma avatar

        Nekoukal sem do zdrojáků, ale očekával bych, že registrace i volání této funkce je levná záležitost. Tzn, zápis do nějaké hash tabulky a pak jen volání fce.

        1. Marek Olšavský avatar

          [Onřej Tůma] To stojí za otestování, díky za hint a udělám to na stejném případě :-).