Es ist wichtig, die Haupt Natur dieser fünf verschiedenen Arten von Daten / Symbolen zu verstehen. :
1. 'my_tbl'
Eine Zeichenfolge, die wörtlich von Unbekannt
Typ . Bei Verwendung in SQL (eingebettet in PLPGSQL -Code oder nicht) wird er zu einem vom -Kontext abgeleiteten Typ gezwungen. . Wenn der Typ nicht bestimmt werden kann, kann ein explizites Guss erforderlich sein. Gefällt: 'my_tbl' ::text
.
2. 'my_tbl' ::text
Die gleiche Zeichenfolge. . Es kann den Namen einer Tabelle halten, aber es ist wirklich nur Text.
3. 'my_tbl' ::Regclass
An Objektkennung (OID)
Für eine registrierte Klasse . Es wird angezeigt und kann als Zeichenfolge eingegeben werden, die einen gültigen Objektnamen darstellt ( 'my_tbl'
). Die Ausgabe wird automatisch schema-qualifiziert ( 'my_schema.my_tbl'
) und / oder doppelt zitiert ( '"my_tbl"'
) Wenn es ansonsten mehrdeutig oder illegal wäre. Es kann eine reguläre Tabelle sein , Sequenz , view , materialisierte Ansicht , Composite -Typ usw. Details in dieser zugehörigen Antwort:
4. my_tbl_var my_tbl
(Kurz für my_tbl_var my_tbl%rowType
)
Im deklarieren
Abschnitt eines PLPGSQL-Codeblocks, der eine variable Deklaration mit einem bekannten Zeilentyp
(a.k.a. Composite -Typ). Der Typ muss in der Systemtabelle pg_class
registriert werden (Gleich wie bei einem Regclass
Variable). Es ist nicht die OID des referenzierten Objekts, sondern der tatsächliche Zeilentyp. my_tbl_var
und my_tbl
sind beide identifiers hier und kann nicht parametrisiert werden. Sie können auch jede Zeile oder Aufzeichnung direkt aufnehmen: (123, 'foo') ::my_tbl
5. my_tbl_var record
Im deklarieren
Abschnitt eines PLPGSQL-Codeblocks, der die Deklaration eines anonymen rekord
. Grundsätzlich ein Platzhalter für einen noch unbekannten Zeilentyp / mit noch undefinierter Struktur. Es kann in meiste verwendet werden Von den Stellen kann ein Zeilentyp verwendet werden. Sie können jedoch nicht darauf zugreifen, bevor die Datensatzvariable zugewiesen wird.
Sie verwirrten 1. , 3. und 4. und löste es mit 5. Stattdessen.
Aber es gibt mehr schief Hier:
-
Sie wählen eine ganze Tabelle aus, aber eine Zeilenvariable (Datensatz) kann jeweils nur eine Zeile halten. Also wird nur der erste zugewiesen und zurückgegeben. Während es keine
bestellen nach
gibt Klausel, das Ergebnis ist willkürlich und kann sich jederzeit ändern. böse Falle. -
Da Sie jetzt einen
-Ertrat
verwenden Geben Sie ein, Sie müssen sicherstellen, dass es zugewiesen wurde, bevor Sie Tests auf den Feldern ausführen können, oder Sie erhalten Ausnahmen für leere Tabellen. In Ihrem Fall ist der Checkrecord_var null
Fast den gleichen Job. In allen Feldern gibt es jedoch einen Eckfall für Zeilen mit Null:dannrecord_var ist null
bewertet true. Noch schwieriger für den Testist nicht null
. Details hier:Ich habe der SQL Fiddle eine Demo hinzugefügt. unten.
-
Die Funktion gibt einen einzelnen Skalar zurück (
boolean
) Wert. Verwendung:RETURN false;
Statt:
RETURN QUERY SELECT false;
Funktion
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 (mit zwei Varianten der Funktion und einer Demo für Zeile ist null).
Wichtige Punkte
-
Verwenden Sie
Diagnostics
ausführen
gefunden wurden . -
Der
if
Ausdruck kann vereinfacht werden. -
Der Parameter ist vom Typ
Regclass
vom Typ, nicht nur ein tischfeiname. Ich würde den irreführenden Namen "TableName" für diesen Parameter nicht verwenden. Das trägt nur zu Ihrer anfänglichen Verwirrung bei. Rufen Sie es
_tbl
auf Stattdessen.
Wenn Sie auch zurücksenden möchten Ein Satz variabler Zeilentyp: