Je důležité porozumět základní povaze těchto pěti různých druhů dat / symbolů :
1. 'my_tbl'
Řetězcový literál unknown typu . Při použití v SQL (vložené do kódu plpgsql nebo ne), je vynuceno na typ odvozený z kontextu . Pokud nelze typ určit, může být vyžadováno explicitní přetypování. Jako:'my_tbl'::text .
2. 'my_tbl'::text
Stejný řetězcový literál přetypuje na zadání text . Může obsahovat název tabulky, ale ve skutečnosti je to jen text.
3. 'my_tbl'::regclass
identifikátor objektu (OID)
pro registrovanou třídu . Je zobrazen a lze jej zadat jako řetězec představující platný název objektu ('my_tbl' ). Výstup je automaticky kvalifikován pro schéma ('my_schema.my_tbl' ) a / nebo dvojité uvozovky ('"mY_TbL"' ), pokud by to bylo nejednoznačné nebo nezákonné jinak. Může to být běžný tabulka , sekvence , zobrazit , materializované zobrazení , složený typ atd. Podrobnosti v této související odpovědi:
4. my_tbl_var my_tbl (zkratka pro my_tbl_var my_tbl%ROWTYPE )
V DECLARE část bloku kódu plpgsql, což je deklarace proměnné s dobře známým typ řádku
(také znám jako kompozitní typ). Typ musí být registrován v systémové tabulce pg_class (stejně jako u regclass proměnná). Není to OID odkazovaného objektu, ale jeho skutečný typ řádku. my_tbl_var a my_tbl oba jsou identifikátory zde a nelze jej parametrizovat. Můžete také odeslat libovolný řádek nebo záznam přímo:(123, 'foo')::my_tbl
5. my_tbl_var record
V DECLARE část bloku kódu plpgsql, která je deklarací anonymního záznam
. V podstatě zástupný symbol pro dosud neznámý typ řádku / s dosud nedefinovanou strukturou. Lze jej použít ve většině z míst lze použít typ řádku. Ale nemůžete z něj přistupovat k polím, dokud není přiřazena proměnná záznamu.
Byl jste matoucí 1. , 3. a 4. a vyřešil to pomocí 5. místo toho.
Ale je toho dalších chyb zde:
-
Vybíráte celou tabulku, ale proměnná řádku (záznamu) může obsahovat pouze jeden řádek najednou. Takže pouze první je přiřazen a vrácen. I když neexistuje
ORDER BYklauzule, výsledek je libovolný a může se kdykoli změnit. Zlá past. -
Protože nyní používáte
recordtypu, musíte se ujistit, že byl přiřazen, než budete moci spustit testy na jeho polích, jinak získáte výjimky pro prázdné tabulky. Ve vašem případě zaškrtněterecord_var IS NULLdělá skoro stejnou práci. Ale pro řádky s NULL ve všech polích existuje rohový případ:pakrecord_var IS NULLhodnotí jako pravdivé. Ještě složitější pro testIS NOT NULL. Podrobnosti zde:Přidal jsem ukázku do SQL housle níže.
-
Funkce vrací jeden skalár (
boolean) hodnotu. Použijte:RETURN false;Místo:
RETURN QUERY SELECT false;
Funkce
CREATE FUNCTION check_valid(_tbl regclass)
RETURNS bool AS
$func$
DECLARE
r record;
_row_ct int;
BEGIN
EXECUTE '
SELECT is_valid, hit_count, hit_limit
FROM ' || _tbl || '
ORDER <whatever>
LIMIT 1' -- replace <whatever> with your sort criteria
INTO r; -- only needed columns
GET DIAGNOSTICS _row_ct = ROW_COUNT;
IF _row_ct = 0 THEN -- necessary, because r may not be assigned
RETURN false;
ELSIF NOT r.is_valid OR r.hit_count > r.hit_limit THEN
RETURN false;
END IF;
RETURN true;
END
$func$ LANGUAGE plpgsql;
SQL Fiddle (se dvěma variantami funkce a ukázkou pro řádek IS NULL).
Hlavní body
-
Použijte
GET DIAGNOSTICSabyste zjistili, zda byly v dynamickém příkazu nalezeny nějaké řádky pomocíEXECUTE. -
IFvýraz lze zjednodušit. -
Parametr je typu
regclass, nejen název tabulky. Pro tento parametr bych nepoužil zavádějící název "tablename". To jen přispívá k vašemu počátečnímu zmatku. Nazývejte to_tblmísto toho.
Pokud byste se také chtěli vrátit sada proměnné typu řádku: