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


183

次の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か?


2
sf_bandsテーブルが存在することを確認しますか?showfinder.sf_bandsは機能しますか?
brian-brazil

1
showfinder.sf_bandsは完全に機能します
Keyslinger

おそらく、私のデータベースがMySQLから移行されたことに注意する必要があります
Keyslinger 2009年

pg_query($ dbconn、$ query)を試すことができますか?暗黙的な接続は、デバッグが難しい問題を引き起こす可能性があり、それを考えられる問題として排除することもできます。また、pg_dbname($ dbconn)を試し、実際にshowfinderに接続されていることを確認できますか?
brian-brazil

1
大文字が問題であることを言及するための+1。PostgreSQLの単一のテーブルから選択できない理由を理解するために1時間を費やしました。なんて恐ろしいプログラムでしょう。
Brain2000、2015年

回答:


298

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

つまり、以下は失敗します。

CREATE TABLE "SF_Bands" ( ... );

SELECT * FROM sf_bands;  -- ERROR!

識別子を区切るには二重引用符を使用します。これにより、テーブルが定義されるときに、大文字と小文字が混在する特定のスペルを使用できます。

SELECT * FROM "SF_Bands";

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

SHOW search_path
  "$user",public

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

SET search_path TO showfinder,public;

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


おっと、許して。私のテーブル名には大文字がなく、データベース名はありません。
Keyslinger 2009年

13
SELECT * FROM SF_BandsPostgresがそのテーブル名を小文字にすることを決定するため、タイプしてもたとえ失敗するようです。奇妙な...
ロマン・スターコフ

3
@romkyns:はい、これは実際にはRDBMSブランド全体でかなり一般的であり、区切りのない識別子は「大文字と小文字を区別しない」と宣伝されます。ただし、小文字を強制することで実装されているため、大文字と小文字は区別されません。これは、テーブルを定義するときにテーブル名の小文字を許可した場合にのみ、テーブルの名前と一致します。CREATE TABLEの実行時に二重引用符の区切り文字を使用する場合、クエリで参照するときに区切り文字を使用する必要があります。
ビルカーウィン、

Postgresは、引用符で囲まれていない場合、テーブル名を自動的に小文字にしますか?それはかなり卑劣です...
アンディ

@Andy、独自のSQLデータベースを作成するときは、大文字と小文字を区別しない識別子を他の方法で実装してください。:)
ビルカーウィン2018年

76

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

  1. テーブル名がすべて小文字のような場合:使用できるアカウント:select * from AcCounTs正常に機能します

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

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

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

私はこのような役に立たないものを覚えておくのは好きではありませんが、あなたはそうしなければなりません;)


1
where-clausesの列名についても同じ
Roland

8
5.のような大文字と小文字の混在は、最も奇妙な部分を見つけるAccountsと失敗しselect * from Accounts;ます。同じ場合は同じではありません。
ローランド

7
引用符を使用しない限り、postgresクエリのすべての名前は小文字です。
Erndob、2017年

1
PHPを使用していませんが、4番目のオプションはうまくいきました
Sayari

2
すべての相互作用をレイアウトしてくれてありがとう!:)
GetHacked

16

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


7
あなたの回答は、以前に受け入れられた回答に何を追加し、22回賛成票を投じ、多くの詳細を提供しますか?
Yaroslav

16

接続文字列にdbnameパラメータを配置します。他のすべてが失敗したときにそれは私のために動作します。

また、選択を行う場合は、を指定しますyour_schemayour_tableこのような:

select * from my_schema.your_table

1
たとえば、my_schema.my_relationにスキーマ名をクエリに入れると、助けになりました。
JoeTidee 2015

2
どうもありがとうございました!それは私が問題を解決するのに役立ちます!しかし、スキーム名を省略できる方法はありますか?
シャーロット

8

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

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

4

これは本当に便利です

SET search_path TO schema,public;

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

データベースプロパティを開き、次にシート「変数」を開いて、ユーザーにこの変数を実際の値とともに追加します。

したがって、ユーザーはデフォルトでこのschema_nameを取得し、schemaNameなしでtableNameを使用できます。


4

スキーマ名とテーブル名は引用符で囲む必要があります。以下のように:

select * from "schemaName"."tableName";

1

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


0

最初にスキーマを追加する必要があります。

SELECT * FROM place.user_place;

それをすべてのクエリに追加したくない場合は、これを試してください:

SET search_path TO place;

今それは動作します:

SELECT * FROM user_place;

0

最も簡単な回避策は、テーブル名とすべての列名を小文字に変更するだけです。問題は解決されます。

例えば:

  • に変更Table_Nametable_name
  • 変更ColumnNamecolumnname
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.