Saya memiliki kueri yang agak rinci dalam skrip yang menggunakan ?
placeholder. Saya ingin menguji kueri yang sama ini langsung dari baris perintah psql (di luar skrip). Saya ingin menghindari masuk dan mengganti semua ?
dengan nilai aktual, sebagai gantinya saya ingin meneruskan argumen setelah kueri.
Contoh:
SELECT *
FROM foobar
WHERE foo = ?
AND bar = ?
OR baz = ? ;
Mencari sesuatu seperti:
%> {select * from foobar where foo=? and bar=? or baz=? , 'foo','bar','baz' };
postgresql
parameters
vol7ron
sumber
sumber
Jawaban:
Anda dapat menggunakan konstruksi -v misalnya
dan kemudian merujuk ke variabel di sql sebagai: v1,: v2 dll
select * from table_1 where id = :v1;
Harap perhatikan bagaimana kami melewatkan nilai string / tanggal menggunakan dua tanda kutip
" '...' "
sumber
\set v3 'another value'
. Ingat saja, ketika Anda perlu mengutip nilai dalam pernyataan SQL, gunakan apostrof di sekitar nama variabel, seperti ini:SELECT * FROM foo WHERE bar = :'v3';
awk
psql -v v1=12 -v v2="'Hello World'" -v v3="'2010-11-12'" -c 'select * from table_1 where id = :v1;'
akan menghasilkan kesalahan sintaksis. Namun, jika bash adalah cangkang Anda, Anda dapat mencoba:psql -v v1=12 -v v2="'Hello World'" -v v3="'2010-11-12'" <<< 'select * from table_1 where id = :v1;'
untuk mendapatkan hasil yang baik.Ditemukan di PostgreSQL, Anda dapat membuat
PREPARE
pernyataan seperti yang Anda bisa dalam bahasa scripting. Sayangnya, Anda tetap tidak dapat menggunakan?
, tetapi Anda dapat menggunakan$n
notasi.Menggunakan contoh di atas:
PREPARE foo(text,text,text) AS SELECT * FROM foobar WHERE foo = $1 AND bar = $2 OR baz = $3 ; EXECUTE foo('foo','bar','baz'); DEALLOCATE foo;
sumber
foo
sedang sibuk dan yang lainPREPARE
harus memiliki nama lain sementara sesi saat ini tidak ditutup. Jika Anda bermain denganPREPARE
kepsql
sulit untuk menemukan setiap kali nama baru danDEALLOCATE
dapat membantu dengan itu =)Dalam psql ada mekanisme melalui
\set name val
perintah, yang seharusnya terkait dengan
-v name=val
opsi baris perintah. Mengutip itu menyakitkan, Dalam banyak kasus, lebih mudah untuk meletakkan seluruh query daging di dalam shell here-document.Edit
Ups, saya seharusnya mengatakan
-v
alih-alih-P
(yang untuk opsi pemformatan) balasan sebelumnya sudah benar.sumber
Anda juga bisa memasukkan parameter di baris perintah psql, atau dari file batch. Pernyataan pertama mengumpulkan detail yang diperlukan untuk menghubungkan ke database Anda.
Prompt terakhir menanyakan nilai kendala, yang akan digunakan dalam klausa kolom WHERE IN (). Ingatlah untuk mengutip tunggal jika string, dan pisahkan dengan koma:
@echo off echo "Test for Passing Params to PGSQL" SET server=localhost SET /P server="Server [%server%]: " SET database=amedatamodel SET /P database="Database [%database%]: " SET port=5432 SET /P port="Port [%port%]: " SET username=postgres SET /P username="Username [%username%]: " SET /P bunos="Enter multiple constraint values for IN clause [%constraints%]: " ECHO you typed %constraints% PAUSE REM pause "C:\Program Files\PostgreSQL\9.0\bin\psql.exe" -h %server% -U %username% -d %database% -p %port% -e -v v1=%constraints% -f test.sql
Sekarang di file kode SQL Anda, tambahkan token v1 di dalam klausa WHERE Anda, atau di mana pun di SQL. Perhatikan bahwa token juga dapat digunakan dalam pernyataan SQL terbuka, tidak hanya dalam file. Simpan ini sebagai test.sql:
SELECT * FROM myTable WHERE NOT someColumn IN (:v1);
Di Windows, simpan seluruh file sebagai file DOS BATch (.bat), simpan test.sql di direktori yang sama, dan luncurkan file batch.
Terima kasih untuk Dave Page, dari EnterpriseDB, untuk skrip asli yang diminta.
sumber
Tampaknya yang Anda minta tidak dapat dilakukan langsung dari baris perintah . Anda juga harus menggunakan fungsi yang ditentukan pengguna di plpgsql atau memanggil kueri dari bahasa skrip (dan pendekatan terakhir membuatnya sedikit lebih mudah untuk menghindari injeksi SQL).
sumber
Saya ingin menawarkan jawaban lain yang terinspirasi oleh komentar @ malcook (menggunakan bash).
Opsi ini dapat bekerja untuk Anda jika Anda perlu menggunakan variabel shell dalam kueri Anda saat menggunakan
-c
bendera . Secara khusus, saya ingin mendapatkan hitungan tabel, yang namanya adalah variabel shell (yang tidak dapat Anda lewati secara langsung saat menggunakan-c
).Asumsikan Anda memiliki variabel shell Anda
Kemudian Anda bisa mendapatkan hasilnya dengan menggunakan
psql -q -A -t -d databasename -c <<< echo "select count(*) from $TABLE_NAME;"
(
-q -A -t
ini hanya untuk mencetak nomor yang dihasilkan tanpa format tambahan)Saya akan mencatat bahwa
echo
di sini-string (<<<
operator) mungkin tidak diperlukan, awalnya saya pikir kutipan itu sendiri akan baik-baik saja, mungkin seseorang dapat menjelaskan alasannya.sumber
Saya akhirnya menggunakan versi jawaban @ vol7ron yang lebih baik:
DO $$ BEGIN IF NOT EXISTS(SELECT 1 FROM pg_prepared_statements WHERE name = 'foo') THEN PREPARE foo(text,text,text) AS SELECT * FROM foobar WHERE foo = $1 AND bar = $2 OR baz = $3; END IF; END$$; EXECUTE foo('foo','bar','baz');
Dengan cara ini Anda selalu dapat mengeksekusinya dalam urutan ini (kueri disiapkan hanya jika belum disiapkan), ulangi eksekusi dan dapatkan hasil dari kueri terakhir.
sumber