Nie można po prostu użyć nazwy tabeli PostgreSQL („relacja nie istnieje”)

183

Próbuję uruchomić następujący skrypt PHP, aby wykonać proste zapytanie do bazy danych:

$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());

Powoduje to następujący błąd:

Zapytanie nie powiodło się: BŁĄD: relacja „sf_bands” nie istnieje

We wszystkich przykładach, które mogę znaleźć, gdzie pojawia się błąd stwierdzający, że relacja nie istnieje, ponieważ używają wielkich liter w nazwie tabeli. Nazwa mojej tabeli nie zawiera wielkich liter. Czy istnieje sposób zapytania do mojej tabeli bez podania nazwy bazy danych, tj. showfinder.sf_bands?

Keyslinger
źródło
2
Czy jesteś pewien, że istnieje tabela sf_bands? Czy działa showfinder.sf_bands?
brian-brazil
1
showfinder.sf_bands działa idealnie
Keyslinger
Być może powinienem zauważyć, że moja baza danych została zmigrowana z MySQL
Keyslinger
Czy możesz wypróbować pg_query ($ dbconn, $ query)? Domniemane połączenie może powodować problemy trudne do debugowania, a także może go wyeliminować jako możliwy problem. Czy możesz także spróbować pg_dbname ($ dbconn), aby upewnić się, że rzeczywiście jest podłączony do wizjera?
brian-brazil
1
+1 za wzmiankę, że problem stanowią duże litery. Spędziłem godzinę próbując dowiedzieć się, dlaczego nie mogłem wybrać jednej tabeli w PostgreSQL. Co za okropny program.
Brain2000

Odpowiedzi:

298

Z tego, co przeczytałem, ten błąd oznacza, że ​​nie odwołujesz się poprawnie do nazwy tabeli. Jednym z powszechnych powodów jest to, że tabela jest zdefiniowana pisownią z wielkimi i małymi literami, a Ty próbujesz wykonać zapytanie wszystkimi małymi literami.

Innymi słowy:

CREATE TABLE "SF_Bands" ( ... );

SELECT * FROM sf_bands;  -- ERROR!

Używaj podwójnych cudzysłowów, aby rozgraniczać identyfikatory, abyś mógł używać określonej pisowni z mieszanymi literami w miarę definiowania tabeli.

SELECT * FROM "SF_Bands";

Jeśli chodzi o Twój komentarz, możesz dodać schemat do „ścieżki_wyszukiwania”, aby po odwołaniu się do nazwy tabeli bez kwalifikowania jej schematu zapytanie dopasowało nazwę tabeli, sprawdzając kolejno każdy schemat. Podobnie jak PATHw powłoce lub include_pathw PHP itp. Możesz sprawdzić bieżącą ścieżkę wyszukiwania schematu:

SHOW search_path
  "$user",public

Możesz zmienić ścieżkę wyszukiwania schematu:

SET search_path TO showfinder,public;

Zobacz także http://www.postgresql.org/docs/8.3/static/ddl-schemas.html

Bill Karwin
źródło
Ups, wybacz mi. Chciałem powiedzieć, że nazwa mojej tabeli nie zawiera wielkich liter, a nie nazwa bazy danych.
Keyslinger
13
Wygląda na to, że nawet jeśli wpiszesz, SELECT * FROM SF_Bandsto nadal się nie powiedzie, ponieważ Postgres zdecyduje, że nazwa tabeli zostanie zapisana małymi literami. Dziwne ...
Roman Starkov
3
@romkyns: Tak, w rzeczywistości jest to dość powszechne w przypadku marek RDBMS, że nieoddzielone identyfikatory są reklamowane jako „bez rozróżniania wielkości liter”. Ale tak naprawdę nie rozróżniają wielkości liter, ponieważ sposób, w jaki zaimplementowali to wymuszanie małych liter. Jest to zgodne z nazwą tabeli tylko wtedy, gdy podczas definiowania tabeli dozwolone było pisanie małymi literami. Jeśli używasz ograniczników podwójnego cudzysłowu podczas TWORZENIA TABELI, musisz używać ograniczników podczas odwoływania się do nich w zapytaniach.
Bill Karwin
Postgres automatycznie pomniejsza nazwy tabel, jeśli nie są one w cudzysłowie? To całkiem dziwne ...
Andy
@ Andy, pisząc własną bazę danych SQL, możesz wprowadzić identyfikatory bez rozróżniania wielkości liter w inny sposób. :)
Bill Karwin
76

Miałem z tym problemy i oto historia (smutna, ale prawdziwa):

  1. Jeśli nazwa tabeli ma małe litery, takie jak: konta, których możesz użyć: select * from AcCounTsi będzie działać poprawnie

  2. Jeśli nazwa tabeli ma małe litery, takie jak: accounts Następujące nie powiedzie się: select * from "AcCounTs"

  3. Jeśli nazwa tabeli ma różne litery, takie jak: Accounts Następujące nie powiedzie się: select * from accounts

  4. Jeśli nazwa tabeli ma różne litery, takie jak: Accounts Następujące będą działać OK: select * from "Accounts"

Nie lubię pamiętać takich bezużytecznych rzeczy, ale musisz;)

Mitzi
źródło
1
To samo dotyczy nazw kolumn w klauzulach where
Roland
8
5. Przypadek mieszany, jak Accounts, zawiedzie select * from Accounts;, znajduję najdziwniejszą część: ten sam przypadek NIE jest identyczny.
Roland
7
To wszystko: wszystkie nazwy w zapytaniu postgres są pisane małymi literami, chyba że używasz cudzysłowów.
Erndob
1
Czwarta opcja działała dla mnie, chociaż nie używam PHP
Sayari
2
Dziękujemy za ustalenie wszystkich interakcji! :)
GetHacked
16

Zapytanie przetwarzania Postgres różni się od innych RDMS. Umieść nazwę schematu w podwójnym cudzysłowie przed nazwą tabeli w ten sposób „SCHEMA_NAME”. „SF_Bands”

Ugur Artun
źródło
7
Co twoja odpowiedź dodaje do poprzednio przyjętej odpowiedzi, która została oceniona 22 razy i zawiera wiele szczegółów?
Jarosław
16

Umieść parametr dbname w ciągu połączenia. To działa dla mnie, podczas gdy wszystko inne zawiodło.

Również podczas wybierania określ your_schema. your_tablelubię to:

select * from my_schema.your_table
JarosPL
źródło
1
Wpisanie nazwy schematu, np. My_schema.my_relation w zapytaniu, pomogło.
JoeTidee
2
Dziękuję Ci bardzo! To naprawdę pomaga mi rozwiązać problem! Ale czy istnieje sposób na pominięcie nazwy schematu?
Charlotte
8

Miałem podobny problem na OSX, ale próbowałem bawić się podwójnymi i pojedynczymi cudzysłowami. W twoim przypadku możesz spróbować czegoś takiego

$query = 'SELECT * FROM "sf_bands"'; // NOTE: double quotes on "sf_Bands"
sav
źródło
4

To jest naprawdę pomocne

SET search_path TO schema,public;

Znalazłem więcej problemów i dowiedziałem się, jak ustawić tę „ścieżkę wyszukiwania”, definiując nowego użytkownika w bieżącej bazie danych.

Otwórz właściwości bazy danych, a następnie otwórz arkusz „Zmienne” i po prostu dodaj tę zmienną dla użytkownika o rzeczywistej wartości.

Więc teraz twój użytkownik otrzyma tę nazwę schematu przez defoult i możesz użyć tableName bez schemaName.

Alexander Kuzichkin
źródło
4

Musisz wpisać nazwę schematu i nazwę tabeli w znaku qutotation. Jak poniżej:

select * from "schemaName"."tableName";
kira
źródło
1

Dla mnie problem polegał na tym, że użyłem zapytania do tej konkretnej tabeli podczas inicjalizacji Django. Oczywiście spowoduje to błąd, ponieważ te tabele nie istniały. W moim przypadku była to get_or_createmetoda w pliku admin.py, która była wykonywana za każdym razem, gdy oprogramowanie uruchamiało jakąkolwiek operację (w tym przypadku migrację). Mam nadzieję, że komuś pomoże.

Özer S.
źródło
0

Najpierw musisz dodać schemat, np

SELECT * FROM place.user_place;

Jeśli nie chcesz dodawać tego do wszystkich zapytań, spróbuj tego:

SET search_path TO place;

Teraz będzie działać:

SELECT * FROM user_place;
Alexis Gamarra
źródło
0

Najłatwiejszym obejściem jest po prostu zmiana nazwy tabeli i wszystkich nazw kolumn na małe litery, a problem zostanie rozwiązany.

Na przykład:

  • Zmień Table_Namena table_name i
  • Zmień ColumnNamenacolumnname
meMadhav
źródło