web-dev-qa-db-ja.com

PostgreSQLテーブル名を単純に使用することはできません(「関係が存在しません」)

次のPHPスクリプトを実行して、簡単なデータベースクエリを実行しようとしています。

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

これにより、次のエラーが生成されます。

クエリに失敗しました:エラー:リレーション "sf_bands"は存在しません

すべての例で、関係が存在しないというエラーが表示される場所を見つけることができます。これは、テーブル名に大文字を使用しているためです。テーブル名に大文字がありません。データベース名、つまりshowfinder.sf_bandsを含めずにテーブルをクエリする方法はありますか?

141
Keyslinger

私が読んだことから、このエラーは、テーブル名を正しく参照していないことを意味します。一般的な理由の1つは、大文字と小文字が混在するテーブルが定義されており、すべて小文字でクエリを実行しようとしていることです。

つまり、次は失敗します。

CREATE TABLE "SF_Bands" ( ... );

SELECT * FROM sf_bands;  -- ERROR!

識別子を区切るには二重引用符を使用して、テーブルの定義時に特定の大文字と小文字のスペルを使用できるようにします。

SELECT * FROM "SF_Bands";

コメントについては、「search_path」にスキーマを追加して、スキーマを修飾せずにテーブル名を参照するときに、クエリが各スキーマを順番にチェックすることでそのテーブル名と一致するようにすることができます。シェルのPATHやPHPのinclude_pathなどと同様に、現在のスキーマ検索パスを確認できます。

SHOW search_path
  "$user",public

スキーマ検索パスを変更できます。

SET search_path TO showfinder,public;

http://www.postgresql.org/docs/8.3/static/ddl-schemas.html も参照してください

245
Bill Karwin

私はこれに問題があり、これは物語です(悲しいが本当です):

  1. テーブル名がすべて小文字の場合:使用できるアカウント:select * from AcCounTs

  2. テーブル名がすべて小文字の場合:accounts次は失敗します:select * from "AcCounTs"

  3. テーブル名が大文字と小文字が混在する場合:Accounts次は失敗します:select * from accounts

  4. テーブル名が次のような大文字と小文字が混在している場合:Accounts以下は問題なく動作します:select * from "Accounts"

私はこのような役に立たないものを覚えているのは好きではありませんが、あなたはする必要があります;)

59
Mitzi

他のRDMSとは異なるPostgresプロセスクエリ。次のように、テーブル名の前にスキーマ名を二重引用符で囲みます。「SCHEMA_NAME」。「SF_Bands」

13
Ugur Artun

接続文字列にdbnameパラメータを入れます。私にとってはうまくいきますが、他のすべてが失敗しました。

また、選択を行うときは、次のようにyour_schema.your_tableを指定します。

select * from my_schema.your_table
12
JarosPL

OSXでも同様の問題がありましたが、二重引用符と一重引用符で遊んでみました。あなたの場合、このようなものを試すことができます

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

これは本当に役に立ちます

SET search_path TO schema,public;

私はこの問題をさらに掘り下げ、現在のデータベースの新しいユーザーに対してdefoultでこの「search_path」を設定する方法を見つけました。

[データベースのプロパティ]を開き、[シート]変数を開いて、実際の値を使用してこの変数をユーザーに追加します。

したがって、ユーザーはdefoultによってこのschema_nameを取得し、schemaNameなしでtableNameを使用できます。

1

私にとって問題は、Djangoが初期化されている間にその特定のテーブルへのクエリを使用したことでした。もちろん、これらのテーブルが存在しなかったため、エラーがスローされます。私の場合、それはadmin.pyファイル内のget_or_createメソッドであり、ソフトウェアが何らかの種類の操作(この場合は移行)を実行するたびに実行されました。それが誰かを助けることを願っています。

0
Özer S.