Tidak bisa menggunakan nama tabel PostgreSQL ("hubungan tidak ada")

183

Saya mencoba menjalankan skrip PHP berikut untuk melakukan kueri basis data sederhana:

$db_host = "localhost";
$db_name = "showfinder";
$username = "user";
$password = "password";
$dbconn = pg_connect("host=$db_host dbname=$db_name user=$username password=$password")
    or die('Could not connect: ' . pg_last_error());

$query = 'SELECT * FROM sf_bands LIMIT 10';
$result = pg_query($query) or die('Query failed: ' . pg_last_error());

Ini menghasilkan kesalahan berikut:

Permintaan gagal: ERROR: relation "sf_bands" tidak ada

Dalam semua contoh yang saya dapat temukan di mana seseorang mendapat kesalahan yang menyatakan bahwa relasinya tidak ada, itu karena mereka menggunakan huruf besar dalam nama tabel mereka. Nama tabel saya tidak memiliki huruf besar. Apakah ada cara untuk query tabel saya tanpa menyertakan nama database, yaitu showfinder.sf_bands?

Keyslinger
sumber
2
Apakah Anda yakin bahwa tabel sf_bands ada? Apakah showfinder.sf_bands berfungsi?
brian-brazil
1
showfinder.sf_bands berfungsi dengan baik
Keyslinger
Mungkin saya harus mencatat bahwa basis data saya dimigrasikan dari MySQL
Keyslinger
Bisakah Anda mencoba pg_query ($ dbconn, $ query)? Koneksi implisit dapat menyebabkan masalah sulit untuk debug, mungkin juga menghilangkannya sebagai masalah yang mungkin terjadi. Bisakah Anda juga mencoba pg_dbname ($ dbconn) untuk memastikan itu memang terhubung ke showfinder?
brian-brazil
1
+1 untuk menyebutkan bahwa huruf besar adalah masalahnya. Saya menghabiskan satu jam mencoba mencari tahu mengapa saya tidak bisa memilih dari satu tabel di PostgreSQL. Program yang mengerikan.
Brain2000

Jawaban:

298

Dari apa yang saya baca, kesalahan ini berarti Anda tidak mereferensikan nama tabel dengan benar. Salah satu alasan umum adalah bahwa tabel didefinisikan dengan ejaan case campuran, dan Anda mencoba untuk menanyakannya dengan semua huruf kecil.

Dengan kata lain, yang berikut ini gagal:

CREATE TABLE "SF_Bands" ( ... );

SELECT * FROM sf_bands;  -- ERROR!

Gunakan tanda kutip ganda untuk membatasi pengidentifikasi sehingga Anda dapat menggunakan ejaan kasus campuran tertentu saat tabel ditentukan.

SELECT * FROM "SF_Bands";

Re komentar Anda, Anda dapat menambahkan skema ke "search_path" sehingga ketika Anda mereferensikan nama tabel tanpa memenuhi syarat skema, kueri akan cocok dengan nama tabel dengan memeriksa setiap skema secara berurutan. Sama seperti PATHdi shell atau include_pathdi PHP, dll. Anda dapat memeriksa jalur pencarian skema Anda saat ini:

SHOW search_path
  "$user",public

Anda dapat mengubah jalur pencarian skema Anda:

SET search_path TO showfinder,public;

Lihat juga http://www.postgresql.org/docs/8.3/static/ddl-schemas.html

Bill Karwin
sumber
Ups, maafkan saya. Saya bermaksud mengatakan bahwa nama tabel saya tidak memiliki huruf besar, bukan nama basis data saya.
Keyslinger
13
Tampaknya bahkan jika Anda mengetik SELECT * FROM SF_Bandsini masih akan gagal, karena Postgres memutuskan untuk mengurangi nama tabel itu untuk Anda. Aneh ...
Roman Starkov
3
@romkyns: Ya, ini sebenarnya cukup umum di seluruh merek RDBMS, bahwa pengidentifikasi yang tidak didahulukan diiklankan sebagai "tidak peka huruf besar-kecil." Tapi mereka tidak benar-benar peka huruf besar-kecil karena cara mereka menerapkannya adalah dengan memaksa huruf kecil. Ini cocok dengan nama tabel hanya jika Anda membiarkan nama tabel diturunkan lebih rendah saat Anda mendefinisikan tabel. Jika Anda menggunakan pembatas kutip ganda ketika Anda membuat tabel, Anda harus menggunakan pembatas ketika Anda referensi dalam kueri.
Bill Karwin
Postgres secara otomatis menurunkan nama tabel jika tidak ada dalam tanda kutip? Itu sangat bodoh ...
Andy
@Andy, ketika Anda menulis database SQL Anda sendiri, jangan ragu untuk mengimplementasikan pengidentifikasi kasus-sensitif dengan cara lain. :)
Bill Karwin
76

Saya punya masalah dengan ini dan ini adalah ceritanya (sedih tapi benar):

  1. Jika nama tabel Anda semua huruf kecil seperti: akun yang dapat Anda gunakan: select * from AcCounTsdan itu akan berfungsi dengan baik

  2. Jika nama tabel Anda semuanya huruf kecil seperti: accounts Berikut ini akan gagal: select * from "AcCounTs"

  3. Jika nama tabel Anda adalah case campuran seperti: Accounts Berikut ini akan gagal: select * from accounts

  4. Jika nama tabel Anda adalah case campuran seperti: Accounts Berikut ini akan berfungsi OK: select * from "Accounts"

Saya tidak suka mengingat hal-hal yang tidak berguna seperti ini tetapi Anda harus;)

Mitzi
sumber
1
Sama untuk nama kolom di mana klausa
Roland
8
5. Kasing campuran, seperti Accounts, akan gagal dengan select * from Accounts;saya menemukan bagian paling aneh: sama-kasus TIDAK identik.
Roland
7
Semua ada untuk itu: semua nama dalam permintaan postgres adalah huruf kecil, kecuali jika Anda menggunakan tanda kutip.
Erndob
1
Opsi keempat bekerja untuk saya, meskipun saya tidak menggunakan PHP
Sayari
2
Terima kasih telah menjabarkan semua interaksi! :)
GetHacked
16

Permintaan proses Postgres berbeda dari RDMS lainnya. Masukkan nama skema dalam kutipan ganda di depan nama tabel Anda seperti ini, "SCHEMA_NAME". "SF_Bands"

Ugur Artun
sumber
7
Apa yang ditambahkan oleh jawaban Anda ke jawaban yang diterima sebelumnya, terunggul sebanyak 22 kali dan dengan banyak detail?
Yaroslav
16

Masukkan parameter dbname di string koneksi Anda. Ini bekerja untuk saya sementara yang lainnya gagal.

Juga saat melakukan pemilihan, tentukan your_schema. your_tableseperti ini:

select * from my_schema.your_table
JarosPL
sumber
1
Memasukkan nama skema, misalnya my_schema.my_relation ke dalam kueri membantu.
JoeTidee
2
Terima kasih banyak! Itu reall membantu saya memecahkan masalah! Tapi apakah ada cara agar saya bisa menghilangkan nama skema?
Charlotte
8

Saya memiliki masalah yang sama pada OSX tetapi mencoba untuk bermain-main dengan tanda kutip ganda dan tunggal. Untuk kasus Anda, Anda dapat mencoba sesuatu seperti ini

$query = 'SELECT * FROM "sf_bands"'; // NOTE: double quotes on "sf_Bands"
sa
sumber
4

Ini sangat membantu

SET search_path TO schema,public;

Saya menggali masalah ini lebih lanjut, dan menemukan tentang cara mengatur "search_path" ini dengan menghapus pengguna baru di basis data saat ini.

Buka DataBase Properties lalu buka Sheet "Variables" dan cukup tambahkan variabel ini untuk pengguna Anda dengan nilai aktual.

Jadi sekarang pengguna Anda akan mendapatkan schema_name ini dengan defoult dan Anda bisa menggunakan tableName tanpa schemaName.

Alexander Kuzichkin
sumber
4

Anda harus menulis nama skema dan nama tabel dalam tanda qutotation. Seperti di bawah ini:

select * from "schemaName"."tableName";
kira-kira
sumber
1

Bagi saya masalahnya adalah, bahwa saya telah menggunakan query ke tabel tertentu sementara Django diinisialisasi. Tentu saja itu akan menimbulkan kesalahan, karena tabel-tabel itu tidak ada. Dalam kasus saya, itu adalah get_or_createmetode dalam file admin.py, yang dieksekusi setiap kali perangkat lunak menjalankan segala jenis operasi (dalam hal ini migrasi). Semoga itu bisa membantu seseorang.

Özer S.
sumber
0

Anda harus menambahkan skema pertama, mis

SELECT * FROM place.user_place;

Jika Anda tidak ingin menambahkan itu di semua kueri lalu coba ini:

SET search_path TO place;

Sekarang akan berfungsi:

SELECT * FROM user_place;
Alexis Gamarra
sumber
0

Solusi termudah adalah Hanya mengubah nama tabel dan semua nama kolom menjadi huruf kecil dan masalah Anda akan teratasi.

Sebagai contoh:

  • Ubah Table_Nameke table_name dan
  • Ubah ColumnNamekecolumnname
meMadhav
sumber