SQLite: emulace RPAD a LPAD

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().

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.

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

  1. 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. [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. 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.

Komentáře jsou uzavřeny.