In MS SQL Server erstelle ich meine Skripte, um anpassbare Variablen zu verwenden:
DECLARE @somevariable int
SELECT @somevariable = -1
INSERT INTO foo VALUES ( @somevariable )
Ich werde dann den Wert von @somevariable
zur Laufzeit ändern , abhängig von dem Wert, den ich in der jeweiligen Situation haben möchte. Da es sich oben im Skript befindet, ist es leicht zu sehen und sich zu erinnern.
Wie mache ich dasselbe mit dem PostgreSQL-Client psql
?
sql
postgresql
variables
psql
Craig Walker
quelle
quelle
Antworten:
Postgres-Variablen werden beispielsweise mit dem Befehl \ set erstellt ...
... und kann dann beispielsweise ersetzt werden als ...
... oder ...
edit: Ab psql 9.1 können Variablen in Anführungszeichen wie folgt erweitert werden:
In älteren Versionen des psql-Clients:
... Wenn Sie die Variable als Wert in einer bedingten Zeichenfolgenabfrage verwenden möchten, z.
... dann müssen Sie die Anführungszeichen in die Variable selbst aufnehmen, da dies nicht funktioniert. Definieren Sie stattdessen Ihre Variable als solche ...
Wenn Sie jedoch wie ich auf eine Situation gestoßen sind, in der Sie aus einer vorhandenen Variablen eine Zeichenfolge erstellen möchten, habe ich den Trick als ...
Jetzt haben Sie sowohl eine zitierte als auch eine nicht zitierte Variable derselben Zeichenfolge! Und so etwas kannst du machen ...
quelle
\set
ist nur fürpsql
Werkzeug, Sie können es nicht in gespeicherten Prozeduren verwenden!psql
Meta-\set
Befehle auf verwirrende Weise mit PostgreSQL-Befehlen.\set myvariable 'value'
ist nicht eine beliebige Zitat in der Variable, im Gegensatz zu dem, was diese Antwort sagt. Verwenden Sie im Zweifelsfall\echo :myvariable
in psql, um den Wert unabhängig von einer Abfrage anzuzeigen.Ein letztes Wort zu PSQL-Variablen:
Sie werden nicht erweitert, wenn Sie sie in einfache Anführungszeichen in die SQL-Anweisung setzen. Das funktioniert also nicht:
Um in einer SQL-Anweisung zu einem Zeichenfolgenliteral zu erweitern, müssen Sie die Anführungszeichen in den Variablensatz aufnehmen. Der Variablenwert muss jedoch bereits in Anführungszeichen gesetzt werden. Dies bedeutet, dass Sie einen zweiten Satz von Anführungszeichen benötigen und der innere Satz maskiert werden muss. Sie brauchen also:
BEARBEITEN : Ab PostgreSQL 9.1 können Sie stattdessen schreiben:
quelle
:'myvariable'
Sie können versuchen, eine WITH- Klausel zu verwenden.
quelle
CREATE TABLE test (name VARCHAR, age INT);
INSERT INTO test (name, age) VALUES ('Jack', 21), ('Jill', 20);
WITH vars AS (SELECT N'Jack' AS name, 21 AS age) SELECT test.* FROM test, vars WHERE test.name = vars.name and test.age = vars.age;
Wie erwartet Jack und Jacks Alter.create table t(x integer);
insert into t(x) with sub as (select 999 as num) select num from sub;
select * from t;
Speziell für
psql
können Siepsql
Variablen auch über die Befehlszeile übergeben. Sie können sie mit übergeben-v
. Hier ist ein Anwendungsbeispiel:Beachten Sie, dass der Doppelpunkt nicht in Anführungszeichen gesetzt ist und der Variablenname selbst in Anführungszeichen gesetzt wird. Seltsame Syntax, ich weiß. Dies funktioniert nur in psql; es wird in (sagen wir) PgAdmin-III nicht funktionieren.
Diese Ersetzung erfolgt während der Eingabeverarbeitung in psql. Sie können also keine Funktion definieren, die verwendet
:'filepath'
und erwartet, dass sich der Wert von:'filepath'
von Sitzung zu Sitzung ändert. Es wird einmal ersetzt, wenn die Funktion definiert ist, und ist danach eine Konstante. Es ist nützlich für Skripte, aber nicht zur Laufzeit.quelle
FWIW, das eigentliche Problem war, dass ich am Ende meines Befehls \ set ein Semikolon eingefügt hatte:
Das Semikolon wurde als tatsächliches Zeichen in der Variablen interpretiert:
Als ich versuchte, es zu benutzen:
...Ich schaff das:
Dadurch konnten nicht nur die Anführungszeichen um das Literal gesetzt werden, sondern der Befehl wurde auch in zwei Teile aufgeteilt (von denen der zweite ungültig war, da er mit "NOINHERIT" begann).
Die Moral dieser Geschichte: PostgreSQL "Variablen" sind wirklich Makros, die bei der Texterweiterung verwendet werden, keine wahren Werte. Ich bin mir sicher, dass das nützlich ist, aber es ist zunächst schwierig.
quelle
Sie müssen eine der prozeduralen Sprachen wie PL / pgSQL verwenden, nicht die SQL-Proc-Sprache. In PL / pgSQL können Sie vars direkt in SQL-Anweisungen verwenden. Für einfache Anführungszeichen können Sie die Anführungszeichenliteralfunktion verwenden.
quelle
postgres (seit Version 9.0) erlaubt anonyme Blöcke in einer der unterstützten serverseitigen Skriptsprachen
http://www.postgresql.org/docs/current/static/sql-do.html
Da sich alles in einer Zeichenfolge befindet, müssen externe Zeichenfolgenvariablen, die ersetzt werden, maskiert und zweimal in Anführungszeichen gesetzt werden. Die Verwendung von Dollar-Anführungszeichen bietet keinen vollständigen Schutz gegen SQL-Injection.
quelle
Ein anderer Ansatz besteht darin, den PostgreSQL GUC-Mechanismus (ab) zum Erstellen von Variablen zu verwenden. Siehe diese vorherige AntwortEinzelheiten und Beispiele finden .
Sie deklarieren den GUC in
postgresql.conf
, ändern dann seinen Wert zur Laufzeit mitSET
Befehlen und erhalten seinen Wert mitcurrent_setting(...)
.Ich empfehle dies nicht für den allgemeinen Gebrauch, aber es könnte in engen Fällen wie dem in der verknüpften Frage erwähnten nützlich sein, in denen das Poster eine Möglichkeit wollte, den Benutzernamen auf Anwendungsebene für Trigger und Funktionen bereitzustellen.
quelle
Ich habe es mit einem temporären Tisch gelöst.
Auf diese Weise hatte ich eine "Variable", die ich für mehrere Abfragen verwenden konnte und die für die Sitzung eindeutig ist. Ich brauchte es, um eindeutige "Benutzernamen" zu generieren, ohne Kollisionen zu haben, wenn Benutzer mit demselben Benutzernamen importiert wurden.
quelle
Ich fand diese Frage und die Antworten äußerst nützlich, aber auch verwirrend. Ich hatte viele Probleme damit, zitierte Variablen zum Laufen zu bringen. Deshalb habe ich es so zum Laufen gebracht:
Auf diese Weise können Sie die Variable in einer Anweisung definieren. Wenn Sie es verwenden, werden einfache Anführungszeichen in die Variable eingebettet.
HINWEIS! Wenn ich nach der zitierten Variablen einen Kommentar einfügte, wurde dieser als Teil der Variablen aufgenommen, als ich einige der Methoden in anderen Antworten ausprobierte. Das hat mich eine Weile wirklich fertig gemacht. Mit dieser Methode werden Kommentare wie erwartet behandelt.
quelle
\set deployment_pass 'string_password'
ALTER USER :deployment_user WITH PASSWORD :'deployment_pass';
Ich vermisse diese Funktion wirklich. Eine ähnliche Möglichkeit besteht nur darin, Funktionen zu verwenden.
Ich habe es auf zwei Arten benutzt:
Perl-Version:
Tabellenversion:
Anmerkungen:
quelle
Variablen in
psql
saugen. Wenn Sie eine Ganzzahl deklarieren möchten, müssen Sie die Ganzzahl eingeben, einen Wagenrücklauf durchführen und die Anweisung in einem Semikolon beenden. Beobachten:Angenommen, ich möchte eine Ganzzahlvariable deklarieren
my_var
und in eine Tabelle einfügentest
:Beispieltabelle
test
:Klar, noch nichts in dieser Tabelle:
Wir deklarieren eine Variable. Beachten Sie, wie das Semikolon in der nächsten Zeile steht!
Jetzt können wir einfügen. Wir müssen diese seltsam
:''
aussehende Syntax verwenden:Es funktionierte!
Erläuterung:
Also ... was passiert, wenn wir das Semikolon in der nächsten Zeile nicht haben? Die Variable? Guck mal:
Wir erklären
my_var
ohne die neue Zeile.Lassen Sie uns auswählen
my_var
.Was zum Teufel ist das? Es ist keine ganze Zahl , es ist eine Zeichenfolge
999;
!quelle
Ich habe eine neue Lösung dafür in einem anderen Thread veröffentlicht .
Es verwendet eine Tabelle zum Speichern von Variablen und kann jederzeit aktualisiert werden. Eine statische unveränderliche Getter-Funktion wird dynamisch (von einer anderen Funktion) erstellt und durch Aktualisierung Ihrer Tabelle ausgelöst. Sie erhalten eine schöne Tischaufbewahrung sowie die blitzschnellen Geschwindigkeiten eines unveränderlichen Getters.
quelle