Der PostgreSQL-Tabellenname kann nicht einfach verwendet werden ("Beziehung existiert nicht")

182

Ich versuche, das folgende PHP-Skript auszuführen, um eine einfache Datenbankabfrage durchzuführen:

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

Dies führt zu folgendem Fehler:

Abfrage fehlgeschlagen: FEHLER: Beziehung "sf_bands" existiert nicht

In allen Beispielen kann ich feststellen, dass jemand eine Fehlermeldung erhält, dass die Beziehung nicht existiert, weil er in seinem Tabellennamen Großbuchstaben verwendet. Mein Tabellenname enthält keine Großbuchstaben. Gibt es eine Möglichkeit, meine Tabelle abzufragen, ohne den Datenbanknamen anzugeben, dh showfinder.sf_bands?

Keyslinger
quelle
2
Sind Sie sicher, dass die Tabelle sf_bands vorhanden ist? Funktioniert showfinder.sf_bands?
Brian-Brasilien
1
showfinder.sf_bands funktioniert perfekt
Keyslinger
Vielleicht sollte ich beachten, dass meine Datenbank von MySQL
Keyslinger
Können Sie pg_query ($ dbconn, $ query) ausprobieren? Die implizite Verbindung kann zu schwer zu debuggenden Problemen führen und sie ebenso wie ein mögliches Problem beseitigen. Können Sie auch pg_dbname ($ dbconn) ausprobieren, um sicherzustellen, dass es tatsächlich mit dem Showfinder verbunden ist?
Brian-Brasilien
1
+1 für die Erwähnung, dass die Großbuchstaben das Problem sind. Ich habe eine Stunde lang versucht herauszufinden, warum ich in PostgreSQL nicht aus einer einzigen Tabelle auswählen konnte. Was für ein schreckliches Programm.
Brain2000

Antworten:

296

Nach dem, was ich gelesen habe, bedeutet dieser Fehler, dass Sie den Tabellennamen nicht richtig referenzieren. Ein häufiger Grund ist, dass die Tabelle in gemischter Schreibweise definiert ist und Sie versuchen, sie in Kleinbuchstaben abzufragen.

Mit anderen Worten, Folgendes schlägt fehl:

CREATE TABLE "SF_Bands" ( ... );

SELECT * FROM sf_bands;  -- ERROR!

Verwenden Sie doppelte Anführungszeichen, um Bezeichner abzugrenzen, damit Sie die spezifische Schreibweise in Groß- und Kleinschreibung verwenden können, wenn die Tabelle definiert ist.

SELECT * FROM "SF_Bands";

Zu Ihrem Kommentar können Sie dem "Suchpfad" ein Schema hinzufügen, sodass die Abfrage, wenn Sie auf einen Tabellennamen verweisen, ohne dessen Schema zu qualifizieren, mit diesem Tabellennamen übereinstimmt, indem jedes Schema der Reihe nach überprüft wird. Genau wie PATHin der Shell oder include_pathin PHP usw. Sie können Ihren aktuellen Schemasuchpfad überprüfen:

SHOW search_path
  "$user",public

Sie können Ihren Schemasuchpfad ändern:

SET search_path TO showfinder,public;

Siehe auch http://www.postgresql.org/docs/8.3/static/ddl-schemas.html

Bill Karwin
quelle
Ups, vergib mir. Ich wollte damit sagen, dass mein Tabellenname keine Großbuchstaben enthält, nicht mein Datenbankname.
Keyslinger
13
Selbst wenn Sie SELECT * FROM SF_Bandsdies eingeben, schlägt dies anscheinend immer noch fehl, da Postgres beschließt, diesen Tabellennamen für Sie in Kleinbuchstaben zu schreiben. Seltsam ...
Roman Starkov
3
@romkyns: Ja, dies ist bei RDBMS-Marken tatsächlich ziemlich häufig, da nicht begrenzte Bezeichner als "Groß- und Kleinschreibung nicht berücksichtigt" beworben werden. Sie unterscheiden jedoch nicht wirklich zwischen Groß- und Kleinschreibung, da die Art und Weise, wie sie implementiert wurden, darin besteht, Kleinbuchstaben zu erzwingen. Dies entspricht nur dann dem Namen der Tabelle, wenn Sie zugelassen haben, dass der Tabellenname beim Definieren der Tabelle in Kleinbuchstaben geschrieben wird. Wenn Sie beim Erstellen von Tabellen Trennzeichen in doppelten Anführungszeichen verwenden, müssen Sie Trennzeichen verwenden, wenn Sie in Abfragen darauf verweisen.
Bill Karwin
Postgres setzt Tabellennamen automatisch in Kleinbuchstaben, wenn sie nicht in Anführungszeichen stehen? Das ist ziemlich blöd ...
Andy
@Andy, wenn Sie Ihre eigene SQL-Datenbank schreiben, können Sie Bezeichner, bei denen die Groß- und Kleinschreibung nicht berücksichtigt wird, auf andere Weise implementieren. :)
Bill Karwin
76

Ich hatte Probleme damit und das ist die Geschichte (traurig, aber wahr):

  1. Wenn Ihr Tabellenname nur in Kleinbuchstaben geschrieben ist, wie: Konten, die Sie verwenden können: select * from AcCounTsund es wird gut funktionieren

  2. Wenn Ihr Tabellenname nur in Kleinbuchstaben geschrieben ist, schlägt accounts Folgendes fehl: select * from "AcCounTs"

  3. Wenn Ihr Tabellenname wie folgt gemischt ist: Accounts Folgendes schlägt fehl: select * from accounts

  4. Wenn Ihr Tabellenname wie folgt gemischt ist: Accounts Folgendes funktioniert in Ordnung: select * from "Accounts"

Ich mag es nicht, mich an solche nutzlosen Dinge zu erinnern, aber du musst;)

Mitzi
quelle
1
Gleiches gilt für Spaltennamen in where-Klauseln
Roland
8
5. Ein gemischter Fall Accountswird scheitern select * from Accounts;, wenn ich den seltsamsten Teil finde: Der gleiche Fall ist NICHT identisch.
Roland
7
Alles, was dazu gehört: Alle Namen in der Postgres-Abfrage sind Kleinbuchstaben, es sei denn, Sie verwenden Anführungszeichen.
Erndob
1
Die vierte Option hat bei mir funktioniert, obwohl ich PHP nicht benutze
Sayari
2
Vielen Dank für alle Interaktionen! :)
GetHacked
16

Postgres-Prozessabfrage unterscheidet sich von anderen RDMS. Setzen Sie den Schemanamen in doppelte Anführungszeichen vor Ihren Tabellennamen wie folgt: "SCHEMA_NAME". "SF_Bands"

Ugur Artun
quelle
7
Was trägt Ihre Antwort zu der zuvor akzeptierten Antwort bei, die 22-mal mit vielen Details bewertet wurde?
Jaroslaw
16

Fügen Sie den Parameter dbname in Ihre Verbindungszeichenfolge ein. Es funktioniert bei mir, während alles andere fehlgeschlagen ist.

Geben Sie auch bei der Auswahl die Option an your_schema. your_tableso was:

select * from my_schema.your_table
JarosPL
quelle
1
Das Einfügen des Schemanamens, z. B. my_schema.my_relation, in die Abfrage hat geholfen.
JoeTidee
2
Vielen Dank! Es hilft mir wirklich, das Problem zu lösen! Aber gibt es eine Möglichkeit, den Schemanamen wegzulassen?
Charlotte
8

Ich hatte ein ähnliches Problem unter OSX, versuchte aber, mit doppelten und einfachen Anführungszeichen herumzuspielen. Für Ihren Fall könnten Sie so etwas versuchen

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

Das ist wirklich hilfreich

SET search_path TO schema,public;

Ich habe diese Probleme genauer untersucht und herausgefunden, wie dieser "Suchpfad" standardmäßig für einen neuen Benutzer in der aktuellen Datenbank festgelegt werden kann.

Öffnen Sie die Datenbankeigenschaften, öffnen Sie das Blatt "Variablen" und fügen Sie diese Variable einfach für Ihren Benutzer mit dem tatsächlichen Wert hinzu.

Jetzt erhält Ihr Benutzer diesen Schemanamen standardmäßig und Sie können tableName ohne schemaName verwenden.

Alexander Kuzichkin
quelle
4

Sie müssen den Schemanamen und den Tabellennamen in das Anführungszeichen schreiben. Wie nachstehend:

select * from "schemaName"."tableName";
kira
quelle
1

Für mich war das Problem, dass ich eine Abfrage für diese bestimmte Tabelle verwendet hatte, während Django initialisiert wurde. Natürlich wird dann ein Fehler ausgegeben, da diese Tabellen nicht vorhanden waren. In meinem Fall war es eine get_or_createMethode in einer admin.py-Datei, die immer dann ausgeführt wurde, wenn die Software irgendeine Operation ausführte (in diesem Fall die Migration). Hoffe das hilft jemandem.

Özer S.
quelle
0

Sie müssen zuerst das Schema hinzufügen, z

SELECT * FROM place.user_place;

Wenn Sie das nicht in allen Abfragen hinzufügen möchten, versuchen Sie Folgendes:

SET search_path TO place;

Jetzt wird es funktionieren:

SELECT * FROM user_place;
Alexis Gamarra
quelle
0

Die einfachste Problemumgehung besteht darin, einfach den Tabellennamen und alle Spaltennamen in Kleinbuchstaben zu ändern und Ihr Problem wird behoben.

Beispielsweise:

  • Wechseln Sie Table_Namezu table_name und
  • Wechseln Sie ColumnNamezucolumnname
meMadhav
quelle