Wie führen Sie eine select-Abfrage in einer DO-block?
Möchte ich den port mit dem folgenden SQL-code aus MS-SQL-Server, PostgreSQL.
DECLARE @iStartYear integer
DECLARE @iStartMonth integer
DECLARE @iEndYear integer
DECLARE @iEndMonth integer
SET @iStartYear = 2012
SET @iStartMonth = 4
SET @iEndYear = 2016
SET @iEndMonth = 1
;WITH CTE
AS
(
SELECT
--@iStartYear AS TheStartYear
@iStartMonth AS TheRunningMonth
,@iStartYear AS TheYear
,@iStartMonth AS TheMonth
UNION ALL
SELECT
--CTE.TheStartYear AS TheStartYear
--@iStartYear AS TheStartYear
CTE.TheRunningMonth + 1 AS TheRunningMonth
--,CTE.TheStartYear + (CTE.TheRunningMonth /12) AS TheYear
,@iStartYear + (CTE.TheRunningMonth / 12) AS TheYear
,(CTE.TheMonth + 1 -1) % 12 + 1 AS TheMonth
FROM CTE
WHERE (1=1)
AND
(
CASE
--WHEN (CTE.TheStartYear + (CTE.TheRunningMonth /12) ) < @iEndYear
WHEN (@iStartYear + (CTE.TheRunningMonth / 12) ) < @iEndYear
THEN 1
--WHEN (CTE.TheStartYear + (CTE.TheRunningMonth /12) ) = @iEndYear
WHEN (@iStartYear + (CTE.TheRunningMonth / 12) ) = @iEndYear
THEN
CASE
WHEN ( (CTE.TheMonth + 1 -1) % 12 + 1 ) <= @iEndMonth
THEN 1
ELSE 0
END
ELSE 0
END = 1
)
)
SELECT * FROM CTE
Dies ist, was ich habe, so weit.
DO $$
DECLARE r record;
DECLARE i integer;
DECLARE __iStartYear integer;
DECLARE __iStartMonth integer;
DECLARE __iEndYear integer;
DECLARE __iEndMonth integer;
DECLARE __mytext character varying(200);
BEGIN
i:= 5;
--RAISE NOTICE 'test'
--RAISE NOTICE 'test1' || 'test2';
__mytext := 'Test message';
--RAISE NOTICE __mytext;
RAISE NOTICE '%', __mytext;
RAISE NOTICE '% %', 'arg1', 'arg2';
--SQL Standard: "CAST( value AS text )" [or varchar]
--PostgreSQL short-hand: "value::text"
__mytext := 'Test ' || i::text;
RAISE NOTICE '%', __mytext;
__mytext := 'mynumber: ' || CAST(i as varchar(33)) || '%';
RAISE NOTICE '%', __mytext;
__iStartYear := 2012;
__iStartMonth := 4;
__iEndYear := 2016;
__iEndMonth := 1;
--PERFORM 'abc';
SELECT 'abc';
-- SELECT __iStartMonth AS TheRunningMonth;
-- RAISE NOTICE 'The raise_test() function began.' + CAST( i AS text ) ;
-- FOR r IN SELECT table_schema, table_name FROM information_schema.tables WHERE table_type = 'VIEW' AND table_schema = 'public'
-- LOOP
-- EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser';
--END LOOP;
END$$;
Wie Sie sehen können, ich hatte ein paar Probleme, wenn zu wollen, um "drucken" mit dem raise notice Funktionalität. Aber ich schaffte es zu lösen, mit Google.
Aus den bisherigen Erfahrungen, kann ich sagen, dass der Postgres-syntax mit CTE ist so ähnlich wie ich nur haben, um einen rekursiven, bevor der CTE, so ist das einzige wirkliche problem ist, dass ich ein paar Variablen definieren, für welche ich eine do-block.
Daraus ergibt sich die einfache Frage, die ich habe:
Wie kann ich "ausführen" wählen Sie eine Abfrage in einer do-block?
Ich will die Ergebnisse sehen Sie in die "data output" - Reiter in pgAdmin3.
Und ich will nicht, um eine Funktion zu erstellen.
InformationsquelleAutor der Frage Stefan Steiger | 2013-02-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
DO
Befehl vs. PL/pgSQL-FunktionDen
Befehl keine Zeilen zurückgeben. Sie können senden
NOTICES
oderRAISE
anderen Nachrichten (Sprache plpgsql) oder schreiben Sie an eine (temporäre) Tabelle und späterSELECT
von ihm, dies zu umgehen.Aber wirklich, sollten Sie erstellen Sie eine (plpgsql) - Funktion statt, wo man definieren kann, einen Rückgabetyp mit der
ZURÜCK
- Klausel oderAUS
/INOUT
- Parameter und Rückkehr aus der Funktion in verschiedener Weise.Wenn Sie nicht möchten, dass die Funktion gespeichert werden und sichtbar für andere-verbindungen, sollten Sie eine "temporäre" - Funktion, die eine nicht dokumentierte, aber gut eingerichtet, verfügen über:
generate_series()
für das problem zur handFür das problem zur hand, die Sie nicht zu benötigen scheinen alle dieser. Nutzen Sie diese einfache Abfrage statt:
Das ist alles.
InformationsquelleAutor der Antwort Erwin Brandstetter
Hier mehr details auf der workaround mit der temporären Tabelle, Erwin beraten, die die wirkliche Antwort auf die Frage, da die Frage mehr auf "während der Entwicklung, wie kann ich schnell Schreibe einen code-block mit einer select-und die Ergebnisse sehen", als es um dieses Problem zu lösen eigentliche Abfrage (die zugrunde liegende Frage war von Anfang an "howto schnell die Entwicklung/debugging-table-valued-functions").
Obwohl ich sagen muss ich würde gerne upvote der generate_series Teil 100 mal 😉
Es ist möglich, wählen Sie die Ergebnisse in eine temporäre Tabelle
und wählen Sie aus der temp-Tabelle außerhalb der do-block
wie diese:
Das ist wirklich die Basis, um schnell eine Abfrage in eine Tabellenwert-Funktion version, die aussieht wie diese btw.:
BTW, haben Sie einen Blick auf den SQL-Server codebloat dies zu erreichen:
Verwandelt sich in diese:
(danke Erwin !) 😉
InformationsquelleAutor der Antwort Stefan Steiger
Dies ist eine nicht zu off-topic (IMHO), und die hilfreich sein können ...
Ich lief in dieses Problem vor kurzem, wo ich brauchte, um das ausführen einer Reihe von Anweisungen in einer Transaktion und wieder etwas (sehr wenig) Daten, die darauf hindeuten würde, an ein PHP-Skript, wie die Transaktion verarbeitet wurde (betroffene Datensätze und benutzerdefinierte Fehler-code).
Festhalten an der Erhöhung kündigen und HEBEN Sie [AUSNAHME] Paradigma, fand ich es am besten wieder eine JSON-string in der BEKANNTMACHUNG/EXCEPTION zurückgegeben wird. Auf diese Weise, alle die PHP app würde tun müssen, ist pg_last_notice() oder pg_last_error() zum abrufen und decodieren des JSON-string.
z.B.
oder
Seit der Rückkehr JSON-Objekt mit dem Namen "std_response" ist eigentlich eine standard-Antwort für alle diese Arten von Skripts, es macht es wirklich einfach zu schreiben unit-tests, da die wrapper-Funktion, lädt und führt das SQL wird immer wieder eine "std_response" - Objekt haben kann, dass es die Werte getestet.
Diesem Paradigma sollte nur verwendet werden, wenn Sie wieder KLEINE Stücke von Daten, die in der RAISE-Nachricht (obwohl ich gesehen habe, bis 96.000 Zeichen, die zurückgegeben werden auf diese Weise - nicht sicher, was die Grenze ist).
Wenn Sie brauchen, um wieder einen größeren Satz von Daten, müssen Sie Sie speichern das Ergebnis in eine Tabelle, aber zumindest können Sie immer noch mit diesem Paradigma zu isolieren genau, welche Datensätze gehören, die mit der Bezeichnung SQL. d.h. die Daten in eine Tabelle mit der UUID und der Rückkehr der UUID in der MITTEILUNG wie folgt:
Die nette Sache über dieses ist, dass, da es ist immer noch strukturiert und beschreibt die Tabelle, wählen Sie die Daten aus, es kann auch verwendet werden, mit unit-tests in der app.
(Alternativ können Sie auch verwenden, Postgresql zum speichern der Ergebnis-Satz in memcache und die Anwendung pickup-dataset von dort aus, so dass Sie nicht haben, um mit der disk-I/O nur für die Speicherung der Ergebnis-setzen Sie die app verwenden, erzeugen einige HTML dann sofort wegwerfen, wenn das Skript beendet ist)
InformationsquelleAutor der Antwort Michael Mügge