Příručka skriptovacího jazyka pgScript

Obsah

Přehled

pgScript se skládá z příkazů pgScript:

příkaz pgScript
    : normální příkaz PostgreSQL SQL (SELECT INSERT CREATE ...)
    | deklarace nebo přiřazení proměnné (DECLARE SET)
    | řídící struktura (IF WHILE)
    | procedura (ASSERT PRINT LOG RMLINE)

Názvy příkazů (SELECT, IF, SET, ...) nejsou citlivé na velikost písmen a musí být zakončené středníkem ;. Identifikátory jsou citlivé na velikost písmen.

Příklady

Dávkové vytváření tabulek

DECLARE @I, @T; -- Názvy proměnných začínají s @
SET @I = 0; -- @I je celé číslo
WHILE @I < 20
BEGIN
    SET @T = 'tabulka' + CAST (@I AS STRING); -- Přetypování @I
    CREATE TABLE @T (id integer primary key, data text);

    SET @I = @I + 1;
END

Vkládání náhodných dat

DECLARE @I, @J, @T, @G;
SET @I = 0;
SET @G1 = INTEGER(10, 29, 1); /* Generátor náhodných celých čísel
                              Jedinečné číslo v rozsahu 10 až 29 */
SET @G2 = STRING(10, 20, 3); /* Generátor náhodných řetězců
                             3 slova v délce 10 až 20 znaků */
WHILE @I < 20
BEGIN
    SET @T = 'tabulka' + CAST (@I AS STRING);

    SET @J = 0;
    WHILE @J < 20
    BEGIN
        INSERT INTO @T VALUES (@G1, '@G2');
        SET @J = @J + 1;
    END

    SET @I = @I + 1;
END

Dávkové mazání tabulek

DECLARE @I, @T; -- Deklarace je volitelná
SET @I = 0;
WHILE 1 -- Vždy pravda
BEGIN
    IF @I >= 20
      BREAK; -- Opustit smyčku pokud @I > 20

    SET @T = 'tabulka' + CAST (@I AS STRING);
    DROP TABLE @T;

    SET @I = @I + 1;
END

Výpis informací na obrazovku

SET @PROGR@M#TITLE = 'pgScript';
PRINT '';
PRINT @PROGR@M#TITLE + ' vlastnosti:';
PRINT '';
PRINT '  * Normální příkazy PostgreSQL';
PRINT '  * Jazyk pro řízení běhu';
PRINT '  * Lokální proměnné';
PRINT '  * Generátory náhodných dat';

Příkazy SQL

V skriptu pgScript můžete spustit LIBOVOLNÝ dotaz PostgreSQL KROMĚ tohoto jednoho:

BEGIN;
END;

To je proto, že BEGIN a END se používají k oddělení bloků. Místo toho použijte:

BEGIN TRANSACTION;
END TRANSACTION;

Seznam příkazů PostgreSQL: http://www.postgresql.org/docs/8.3/interactive/sql-commands.html

Proměnné

Jsou dva hlavní typy proměnných: jednoduché proměnné a záznamy (množiny výsledků složené z řádků a sloupců).

Názvy proměnných začínají s @ a mohou se skládat z písmen, číslic, _, #, @.

Typ proměnné se odhadne automaticky v závislosti na druhu hodnoty, kterou obsahuje. Může to být jeden z těchto: číslo (reálné nebo celé), řetězec, záznam.

Jednoduché proměnné

Deklarace jednoduché proměnné

Deklarace jednoduché proměnné je volitelná.

DECLARE @A, @B;
DECLARE @VAR1;
Přiřazení jednoduché proměnné

Provádí se příkazem SET. Typ proměnné závisí na hodnotě, která je do ní přiřazená.

SET @A = 1000, @B = 2000;   -- @A a @B jsou celá čísla
SET @C = 10e1, @D = 1.5;    -- @C a @D jsou reálná čísla
SET @E = 'ab', @F = 'a''b'; -- @E a @F jsou řetězce
SET @G = "ab", @H = "a\"b"; -- @G a @H jsou řetězce

Neinicializované proměnné se automaticky nastaví na prázdný řetězec. Proměnnou je možné libovolně přepisovat.

PRINT @A;      -- Vytiskne prázdný řetězec
SET @A = 1000; -- @A je inicializováno jako celé číslo
PRINT @A;      -- Vytiskne 1000
SET @A = 'ab'; -- @A se změní na řetězec
PRINT @A;      -- Vytiskne ab
Generátory dat

Generátory dat umožňují uživatelům generovat náhodné hodnoty. Je několik typů generátorů, každý generuje různé typy dat. Proměnná inicializovaná generátorem se chová jako běžná jednoduchá proměnná, akorát že při každém použití má jinou hodnotu.

SET @A = INTEGER(100, 200);
PRINT @A; -- Vytiskne celé číslo z rozsahu do 100 do 200
PRINT @A; -- Vytiskne jiné celé číslo z rozsahu od 100 do 200

Proměnná může obsahovat generátor, ale její typ je jeden z následujících: číslo (reálné nebo celé), řetězec. Seznam dostupných generátorů a k nim přidružených typů najdete v kapitole Generátory náhodných dat.

Záznamy

Deklarace záznamu

Deklarace záznamu je povinná. Musí být uveden název každého sloupce i když nebude později použitý.

DECLARE @R1 { @A, @B }, @R2 { @A, @C }; -- Dva záznamy se dvěma sloupci
DECLARE @R3 { @A, @B, @C, @D };         -- Jeden záznam se čtyřmi sloupci

Počet řádků je dynamický: viz následující sekce.

Přiřazení záznamu

Přístup k určitému místu v záznamu je dán číslem řádku (začíná se od 0) a buď názvem sloupce (uzavřeném do uvozovek) nebo číslem sloupce (začíná se od 0). Takto specifikované místo se chová jako jednoduchá proměnná. Upozorněme, že záznam nemůže obsahovat další záznam.

SET @R1[0]['@A'] = 1; -- První řádek a první sloupec
SET @R1[0][0] = 1;    -- To stejné umístění
SET @R1[4]['@B'] = 1; -- Pátý řádek a sedmý sloupec
SET @R1[0][1] = 1;    -- To stejné umístění

V předchozím příkladu se vloží automaticky tři řádky mezi první a pátý řádek. Použití neplatného čísla nebo názvu sloupce způsobí výjimku.

Specifikované místo je možné použít jako regulérní proměnnou. A specifikovaný řádek rovněž.

SET @R1[0][0] = @R3[0][1], @A = @R2[0][0]; -- Chová se jako jednoduchá proměnná
SET @A = @R1[1]; -- @A se stane záznamem, který obsahuje první řádek z @R1

Nezapomeňte, že nelze použít SET @R1[0][0] = @R2, protože záznam nemůže obsahovat záznam.

Za to je možné přiřadit záznam do proměnné, v takovém případě není nutné proměnnou deklarovat:

SET @A = @R3; -- @A se stane záznamem, protože je do něj přiřazený záznam
Dotazy SQL

Některé dotazy SQL vrací záznamy. Pokud je dotazem SELECT, vrací výsledky dotazu. Ostatní dotazy vrací jednořádkový záznam (true) pokud dopadly úspěšně, v opačném případě záznam s nulovým počtem řádků (false).

SET @A = SELECT * FROM tabulka;  -- @A je záznam s výsledkem dotazu
SET @B = INSERT INTO tabulka ...; -- @B je jednořádkový záznam, pokud dotaz dopadl úspěšně
Funkce záznamů

Viz Funkce.

Přetypování

Proměnnou je možné změnit z jednoho typu na jiný pomocí funkce přetypování:

SET @A = CAST (@B AS STRING);
SET @A = CAST (@B AS REAL);
SET @A = CAST (@B AS INTEGER);
SET @A = CAST (@B AS RECORD);

Pokud se konvertuje záznam na řetězec, změní se na jeho textovou reprezentaci. Pokud se konvertuje na číslo, nejprve se záznam zkonvertuje na řetězec a potom na číslo (viz konverze řetězců).

Pokud se konvertuje číslo na řetězec, změní se na jeho textovou reprezentaci. Pokud se konvertuje na záznam, změní se na záznam s jedním řádkem a jedním sloupcem, který obsahuje číslo.

Pokud se konvertuje řetězec na číslo, tak pokud řetězec představuje číslo změní se na číslo, jinak se vyvolá výjimka. Pokud se konvertuje na záznam, pokusí se program v řetězci najít vzor záznamu. Pokud ho nenajde provede konverzi na záznam s jedním řádkem a jedním sloupcem, který obsahuje řetězec. Vzor záznamu je:

SET @B = '(1, "abc", "ab\\"")(1, "abc", "ab\\"")'; -- @B je řetězec
SET @B = CAST (@B AS RECORD); -- @B se změnilo na záznam s dvěma řádky a třemi sloupci

Zapamatujte si, že řetězec je uzavřený do apostrofů. Řetězec v záznamu musí být uzavřený v uvozovkách zakončených s \\ (zpětné lomítko je zdvojené, protože je už i speciálním znakem pro řetězec v apostrovech).

Operace

Operace lze provádět pouze mezi operandy stejného typu. Pokud jsou různého typu, lze to řešit přetypováním.

Výsledkem porovnávání je číslo 0 nebo 1.

Řetězce

Porovnávání: = <> > < <= >= AND OR

Spojování: +

SET @B = @A + 'abcdef'; -- @A musí být řetězec a @B bude řetězec

Logická hodnota: neprázdný řetězec je true, prázdný řetězec je false

Inverze logické hodnoty: NOT

Porovnávání bez citlivosti na velikost písmen: ~=

Čísla

Porovnávání: = <> > < <= >= AND OR

Aritmetika: + - * / %

SET @A = CAST ('10' AS INTEGER) + 5; -- řetězec '10' se převede na číslo

Logická hodnota: 0 je false, cokoliv jiného je true

Inverze logické hodnoty: NOT (poznámka: NOT NOT 10 = 1)

Aritmetická operace obsahující alespoň jedno reálné číslo vrátí jako výsledek reálné číslo:

SET @A = 10 / 4.; -- 4. je reálné číslo, takže výsledek je reálné číslo: @A = 2.5
SET @A = 10 / 4;  -- 4 je celé číslo, takže výsledkem je celé číslo: @A = 2
Záznamy

Porovnávání: = <> > < <= >= AND OR

Logická hodnota: záznam s nulovým počtem řádků je false, cokoliv jiného je true

Inverze logické hodnoty: NOT

Porovnávání záznamů je o inkluzi a exkluzi. Pořadí řádků není podstatné. <= znamená, že každý řádek v levém operandu má odpovídající v pravém operandu. >= je opakem. = znamená, že musí být pravdivé současně <= i >=

Porovnávání se provádí na řetězcích: i když záznam obsahuje čísla jako 10 a 1e1, dostaneme '10' <> '1e1'.

Struktury pro řízení běhu

Struktury podmínek

IF podmínka
BEGIN
    přikazy pgScript
END
ELSE
BEGIN
    příkazy pgScript
END

Příkazy pgScript jsou nepovinné. Klíčová slova BEGIN a END jsou volitelná v případě, že příkaz pgScript je jen jeden.

Struktury cyklů

WHILE podmínka
BEGIN
    příkazy pgScript
END

Příkazy pgScript jsou nepovinné. Klíčová slova BEGIN a END jsou volitelná v případě, že příkaz pgScript je jen jeden.

BREAK ukončí smyčku cyklu WHILE, ve které je uzavřený, zatímco CONTINUE způsobí přechod na další iteraci cyklu, ve kterém byl vyvolaný. RETURN funguje podobně jako BREAK.

WHILE podmínka1
BEGIN
    IF podmínka2
    BEGIN
        BREAK;
    END
END

Podmínky

Podmínky jsou ve skutečnosti výsledky operací. Například porovnávání řetězců 'ab' = 'ac' vrátí false.

IF 'ab' ~= 'AB' -- Porovnávání bez citlivosti na velikost písmen, jehož výsledkem je 1 (true)
BEGIN
    -- Toto nastane
END

IF 0 -- false
BEGIN
    -- Toto nenastane
END
ELSE
BEGIN
    -- Toto nastane
END

WHILE 1
BEGIN
    -- Nekonečná smyčka: použijte BREAK pro ukončení
END

Výsledek dotazu SQL SELECT je možné přímo použít jako podmínku. Dotaz se musí uzavřít do závorek:

IF (SELECT 1 FROM tabulka)
BEGIN
    -- Toto znamená, že tabulka existuje, jinak by podmínka musela být false
END

Doplňující funkce a procedury

Procedury

Procedury nevrací výsledek. Musí se použít na samostatném řádku a nelze je přiřadit proměnné.

Print

Výpíše výraz na obrazovku:

PRINT 'Hodnota @A je' + CAST (@A AS STRING);
Assert

Vyvolá výjimku pokud je výsledkem výrazu false:

ASSERT 5 > 3 AND 'a' = 'a';
RmLine

Odebere konkrétní řádek ze záznamu:

RMLINE(@R[1]); -- Odebere druhý řádek @R

Funkce

Funkce vrací výsledek. Vrácený výsledek můžete přiřadit do proměnné, podobně jako u operace CAST.

Trim

Odstraní přebytečné mezery obklopující řetězec:

SET @A = TRIM(' a '); -- @A = 'a'
Lines

Vrátí počet řádků v záznamu:

IF LINES(@R) > 0
BEGIN
    -- Zpracování
END
Columns

Vrátí počet sloupců v záznamu:

IF COLUMNS(@R) > 0
BEGIN
    -- Zpracování
END

Generátory náhodných dat

Přehled o generátorech

Generátor náhodných dat můžete do proměnné přiřadit příkazem SET. Proměnná pak bude mít, pokaždé když se použije, jinou hodnotu.

Jinak se proměnná používá tak, jak je běžné:

SET @G = STRING(10, 20, 2);
SET @A = @G; -- @A obsahuje náhodný řetězec
SET @B = @G; -- @B obsahuje jiný náhodný řetězec
PRINT @G,    -- Vypíše ještě jiný náhodný řetězec

Sekvence a semínka

Běžnými parametry datových generátorů jsou sekvence a semínka.

sekvence znamená, že hodnoty se generují v náhodném pořadí, každá hodnota se ale vyskytne maximálně jednou, dokud se sekvence nezačne znovu. To lze s úspěchem využít pro sloupce s omezením jedinečnosti UNIQUE. Např. následující generátor:

SET @G = INTEGER(10, 15, 1); -- 1 znamená, že se bude generovat sekvence

může generovat třeba takové hodnoty: 14 12 10 13 11 15 14 12 10 13 11..., kde se každé číslo objeví jen jednou, dokud se generátor nespustí znovu od začátku.

Parametr sequence musí být celé číslo. Pokud je 0, tak se negeneruje sekvence (výchozí volba), jakékoliv jiné číslo generuje sekvenci.

semínko je celé číslo, které inicializuje generátor. Dva generátory se stejnými parametry a stejným semínkem budou generovat přesně stejné hodnoty.

semínko musí být celé číslo, které se použije přímo k inicializaci generátoru náhodných dat.

Generátory dat

Volitelné parametry jsou uvedené v hranatých závorkách.

Generátor
    : INTEGER ( min, max, [sekvence], [semínko] );
    | REAL ( min, max, přesnost, [sekvence], [semínko] );
    | DATE ( min, max, [sekvence], [semínko] );
    | TIME ( min, max, [sekvence], [semínko] );
    | DATETIME ( min, max, [sekvence], [semínko] );
    | STRING ( min, max, [počet], [semínko] );
    | REGEX ( regvýraz, [semínko] );
    | FILE ( cesta, [sekvence], [semínko], [kódování] );
    | REFERENCE ( tabulka, sloupec, [sekvence], [semínko] );
Celá čísla
INTEGER ( min, max, [sekvence], [semínko] );
INTEGER ( -10, 10, 1, 123456 );

min je celé číslo, max je celé číslo, sekvence je celé číslo a semínko je rovněž celé číslo.

Realná čísla
REAL ( min, max, přesnost, [sekvence], [semínko] );
REAL ( 1.5, 1.8, 2, 1 );

min je číslo, max je číslo, přesnost je celé číslo, které udává počet desetinných míst (mělo by být menší než 30), sekvence je celé číslo a semínko je celé číslo.

Datumy
DATE ( min, max, [sekvence], [semínko] );
DATE ( '2008-05-01', '2008-05-05', 0 );

min je řetězec představujíc datum, max je řetězec představující datum, sekvence je celé číslo a semínko je celé číslo.

Časy
TIME ( min, max, [sekvence], [semínko] );
TIME ( '00:30:00', '00:30:15', 0 );

min je řetězec představující čas, max je řetězec představující čas, sekvence je celé číslo a semínko je celé číslo.

Časová razítka (datum/čas)
DATETIME ( min, max, [sekvence], [semínko] );
DATETIME ( '2008-05-01 14:00:00', '2008-05-05 15:00:00', 1 );

min je řetězec představující časové razítko, max je řetězec představující časové razítko, sekvence je celé číslo a semínko je celé číslo.

Řetězce
STRING ( min, max, [počet], [semínko] );
STRING ( 10, 20, 5 );

min je celé číslo udávající minimální délku slova, max je celé číslo udávající maximální délku slova, počet je celé číslo udávající počet slov (výchozí je: 1) a semínko je celé číslo.

V předchozím příkladu se bude generovat 5 slov (oddělených mezerami) s délkou od 10 do 20 znaků.

Řetězce z regulárního výrazu
REGEX ( regvýraz, [semínko] );
REGEX ( '[a-z]{1,3}@[0-9]{3}' );

regvýraz je řetězec představující jednoduchý regulární výraz a semínko je celé číslo.

Jednoduchý regulární výraz se skládá z:

Lze určit minimální a maximální délku pro předcházející množinu nebo znak:

Poznámka: dávejte pozor při zadávání mezer, protože např. 'a {3}' znamená jeden znak a následovaný třemi mezerami, protože 3 se váže k poslednímu znaku, což je v tomto případě mezera.

Pokud potřebujete zadat [ ] \ { nebo }, musíte tyto znaky ošetřit zpětným lomítkem, protože se jedná o znaky se speciálním významem. Nezapomeňte použít zdvojené zpětné lomítko: '\\[{3}' pro tři znaky [.

Řetězce ze slovníkových souborů
FILE ( cesta, [sekvence], [semínko], [kódování] );
FILE ( 'soubor.txt', 0, 54321, 'utf-8' );

cesta je řetězec představující cestu k textovému souboru, sekvence je celé číslo, semínko je celé číslo a kódování je řetězec představující znakovou sadu použitou v souboru (výchozí je kódování podle nastavení v systému).

Generují se celá čísla v rozmezí od 1 do počtu řádků souboru a vrátí se příslušný řádek. Pokud soubor neexistuje, vyvolá se výjimka.

Jako kódování je podporovaná většina známých kódování jako utf-8, utf-16le, utf-16be, iso-8859-1, ...

Odkaz na jiné pole
REFERENCE ( tabulka, sloupec, [sekvence], [semínko] );
REFERENCE ( 'tab', 'col', 1 );

tabulka je řetězec představující název tabulky, sloupec je řetězec představující název sloupce tabulky, sekvence je celé číslo a semínko je celé číslo.

Účel použití je pro generování dat do sloupců určených jako cizí klíče.