Di MS SQL Server, saya membuat skrip untuk menggunakan variabel yang dapat disesuaikan:
DECLARE @somevariable int
SELECT @somevariable = -1
INSERT INTO foo VALUES ( @somevariable )
Saya kemudian akan mengubah nilai @somevariable
saat runtime, tergantung pada nilai yang saya inginkan dalam situasi tertentu. Karena berada di bagian atas skrip, mudah dilihat dan diingat.
Bagaimana saya melakukan hal yang sama dengan klien PostgreSQL psql
?
sql
postgresql
variables
psql
Craig Walker
sumber
sumber
Jawaban:
Variabel Postgres dibuat melalui perintah \ set, misalnya ...
... dan kemudian dapat diganti, misalnya, seperti ...
... atau ...
sunting: Pada psql 9.1, variabel dapat diperluas dalam tanda kutip seperti pada:
Dalam versi yang lebih lama dari klien psql:
... Jika Anda ingin menggunakan variabel sebagai nilai dalam kueri string bersyarat, seperti ...
... maka Anda perlu memasukkan tanda kutip dalam variabel itu sendiri karena hal di atas tidak akan berfungsi. Alih-alih, tentukan variabel Anda sebagai ...
Namun, jika, seperti saya, Anda mengalami situasi di mana Anda ingin membuat string dari variabel yang ada, saya menemukan trik untuk menjadi ini ...
Sekarang Anda memiliki variabel yang dikutip dan tidak dikutip dari string yang sama! Dan Anda dapat melakukan sesuatu seperti ini ....
sumber
\set
hanya untukpsql
alat, Anda tidak dapat menggunakannya dalam prosedur tersimpan!psql
meta-perintah\set
dengan perintah PostgreSQL dengan cara yang membingungkan.\set myvariable 'value'
tidak tidak termasuk kutipan apapun di dalam variabel, bertentangan dengan apa yang dikatakan jawaban ini. Jika ragu, gunakan\echo :myvariable
dalam psql untuk menampilkan nilai secara independen dari kueri apa pun.Satu kata terakhir pada variabel PSQL:
Mereka tidak berkembang jika Anda menyertakannya dalam tanda kutip tunggal dalam pernyataan SQL. Jadi ini tidak berhasil:
Untuk memperluas ke string literal dalam pernyataan SQL, Anda harus menyertakan tanda kutip dalam set variabel. Namun, nilai variabel sudah harus dilampirkan dalam tanda kutip, yang berarti bahwa Anda memerlukan set tanda kutip kedua , dan set dalam harus diloloskan. Maka Anda membutuhkan:
EDIT : dimulai dengan PostgreSQL 9.1, Anda dapat menulis sebagai gantinya:
sumber
:'myvariable'
Anda dapat mencoba menggunakan klausa DENGAN .
sumber
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;
Ouputs usia Jack dan Jack, seperti yang diharapkan.create table t(x integer);
insert into t(x) with sub as (select 999 as num) select num from sub;
select * from t;
Khusus untuk
psql
, Anda dapat melewatkanpsql
variabel dari baris perintah juga; Anda dapat melewati mereka-v
. Berikut ini contoh penggunaan:Perhatikan bahwa titik dua tidak dikutip, maka nama variabelnya dikutip. Sintaks aneh, saya tahu. Ini hanya berfungsi di psql; itu tidak akan bekerja di (katakanlah) PgAdmin-III.
Substitusi ini terjadi selama pemrosesan input dalam psql, jadi Anda tidak dapat (katakanlah) mendefinisikan fungsi yang menggunakan
:'filepath'
dan mengharapkan nilai:'filepath'
untuk berubah dari sesi ke sesi. Ini akan diganti sekali, ketika fungsi didefinisikan, dan kemudian akan menjadi konstan setelah itu. Ini berguna untuk scripting tetapi tidak digunakan runtime.sumber
FWIW, masalah sebenarnya adalah bahwa saya telah menyertakan tanda titik koma di akhir perintah \ set saya:
Titik koma ditafsirkan sebagai karakter aktual dalam variabel:
Jadi ketika saya mencoba menggunakannya:
...Saya mengerti:
Itu tidak hanya gagal untuk mengatur tanda kutip di sekitar literal, tetapi membagi perintah menjadi 2 bagian (yang kedua tidak valid karena dimulai dengan "NOINHERIT").
Moral dari cerita ini: "variabel" PostgreSQL benar-benar makro yang digunakan dalam ekspansi teks, bukan nilai sebenarnya. Saya yakin itu berguna, tetapi pada awalnya sulit.
sumber
Anda perlu menggunakan salah satu bahasa prosedural seperti PL / pgSQL bukan bahasa proc SQL. Dalam PL / pgSQL Anda dapat menggunakan vars tepat di pernyataan SQL. Untuk kutipan tunggal, Anda dapat menggunakan fungsi literal kutipan.
sumber
postgres (sejak versi 9.0) memungkinkan blok anonim dalam bahasa skrip sisi server yang didukung
http://www.postgresql.org/docs/current/static/sql-do.html
Karena semuanya ada di dalam string, variabel string eksternal yang disubstitusi harus diloloskan dan dikutip dua kali. Sebaliknya, menggunakan kutipan dolar tidak akan memberikan perlindungan penuh terhadap injeksi SQL.
sumber
Pendekatan lain adalah (ab) menggunakan mekanisme GUC PostgreSQL untuk membuat variabel. Lihat jawaban sebelumnya untuk detail dan contoh.
Anda mendeklarasikan GUC di
postgresql.conf
, lalu ubah nilainya saat runtime denganSET
perintah dan dapatkan nilainya dengancurrent_setting(...)
.Saya tidak merekomendasikan ini untuk penggunaan umum, tetapi bisa berguna dalam kasus-kasus sempit seperti yang disebutkan dalam pertanyaan terkait, di mana poster menginginkan cara untuk menyediakan nama pengguna tingkat aplikasi untuk memicu dan fungsi.
sumber
Saya memecahkannya dengan tabel temp.
Dengan cara ini, saya memiliki "variabel" yang dapat saya gunakan pada beberapa kueri, yang unik untuk sesi ini. Saya membutuhkannya untuk menghasilkan "nama pengguna" yang unik sementara masih tidak memiliki tabrakan jika mengimpor pengguna dengan nama pengguna yang sama.
sumber
Saya menemukan pertanyaan ini dan jawabannya sangat berguna, tetapi juga membingungkan. Saya memiliki banyak masalah dalam membuat variabel yang dikutip berfungsi, jadi inilah cara saya membuatnya berfungsi:
Dengan cara ini Anda dapat mendefinisikan variabel dalam satu pernyataan. Saat Anda menggunakannya, tanda kutip tunggal akan dimasukkan ke dalam variabel.
CATATAN! Ketika saya memberikan komentar setelah variabel yang dikutip itu tersedot sebagai bagian dari variabel ketika saya mencoba beberapa metode dalam jawaban lain. Itu benar-benar mengacaukan saya untuk sementara waktu. Dengan metode ini, komentar tampaknya diperlakukan seperti yang Anda harapkan.
sumber
\set deployment_pass 'string_password'
ALTER USER :deployment_user WITH PASSWORD :'deployment_pass';
Saya sangat merindukan fitur itu. Satu-satunya cara untuk mencapai sesuatu yang serupa adalah menggunakan fungsi.
Saya telah menggunakannya dalam dua cara:
Versi Perl:
Versi tabel:
Catatan:
sumber
Variabel dalam
psql
mengisap. Jika Anda ingin mendeklarasikan bilangan bulat, Anda harus memasukkan bilangan bulat, lalu lakukan carriage return, lalu akhiri pernyataan dalam tanda titik koma. Mengamati:Katakanlah saya ingin mendeklarasikan variabel integer
my_var
dan memasukkannya ke dalam tabeltest
:Tabel contoh
test
:Jelas, belum ada di tabel ini:
Kami mendeklarasikan variabel. Perhatikan bagaimana titik koma ada di baris berikutnya!
Sekarang kita bisa memasukkan. Kita harus menggunakan
:''
sintaks yang terlihat aneh ini :Berhasil!
Penjelasan:
Jadi ... apa yang terjadi jika kita tidak memiliki titik koma di baris berikutnya? Variabelnya? Lihat:
Kami menyatakan
my_var
tanpa garis baru.Ayo pilih
my_var
.WTF apakah itu? Ini bukan bilangan bulat , ini sebuah string
999;
!sumber
Saya telah memposting solusi baru untuk ini di utas lain .
Ini menggunakan tabel untuk menyimpan variabel, dan dapat diperbarui kapan saja. Fungsi pengambil statis yang tidak bergerak dibuat secara dinamis (oleh fungsi lain), dipicu oleh pembaruan ke tabel Anda. Anda mendapatkan penyimpanan meja yang bagus, ditambah kecepatan cepat dari pengambil yang tidak berubah.
sumber