Невозможно просто использовать имя таблицы 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?
Брайан-Бразилия

1
showfinder.sf_bands работает отлично
Кейслингер,

Возможно, я должен отметить, что моя база данных была перенесена из MySQL
Keyslinger

Можете ли вы попробовать pg_query ($ dbconn, $ query)? Неявное соединение может вызвать проблемы, которые трудно отладить, а также устранить их как возможную проблему. Вы также можете попробовать pg_dbname ($ dbconn), чтобы убедиться, что он действительно подключен к showfinder?
Брайан-Бразилия

1
+1 за упоминание о том, что заглавные буквы являются проблемой. Я потратил час, пытаясь понять, почему я не могу выбрать одну таблицу в PostgreSQL. Какая ужасная программа.
Brain2000

Ответы:


298

Из того, что я прочитал, эта ошибка означает, что вы не ссылаетесь на имя таблицы правильно. Одной из распространенных причин является то, что таблица определена с помощью написания в смешанном регистре, и вы пытаетесь запросить ее со всеми строчными буквами.

Другими словами, следующее терпит неудачу:

CREATE TABLE "SF_Bands" ( ... );

SELECT * FROM sf_bands;  -- ERROR!

Используйте двойные кавычки для разделения идентификаторов, чтобы вы могли использовать конкретное написание в смешанном регистре, как определена таблица.

SELECT * FROM "SF_Bands";

Что касается вашего комментария, вы можете добавить схему в «search_path», чтобы при обращении к имени таблицы без определения ее схемы запрос совпадал с именем таблицы, проверяя каждую схему по порядку. Как PATHв оболочке или include_pathв PHP и т. Д. Вы можете проверить текущий путь поиска схемы:

SHOW search_path
  "$user",public

Вы можете изменить путь поиска схемы:

SET search_path TO showfinder,public;

Смотрите также http://www.postgresql.org/docs/8.3/static/ddl-schemas.html


Ой, прости меня. Я хотел сказать, что в имени моей таблицы нет заглавных букв, а не имя базы данных.
Кейслингер,

13
Похоже, что даже если вы наберете SELECT * FROM SF_Bandsэто, все равно не получится, потому что Postgres решит сделать строчные имена для этой таблицы. Странно ...
Роман Старков

3
@romkyns: Да, это на самом деле довольно распространено среди брендов RDBMS, что неограниченные идентификаторы объявляются как «нечувствительные к регистру». Но они на самом деле не чувствительны к регистру, потому что способ, которым они реализованы, заключается в использовании строчных букв. Это соответствует имени таблицы только в том случае, если вы позволили вводить имя таблицы в нижнем регистре при определении таблицы. Если вы используете разделители в двойных кавычках, когда создаете TABLE, вы должны использовать разделители, когда ссылаетесь на них в запросах.
Билл Карвин

Postgres автоматически вводит имена таблиц в нижнем регистре, если они не в кавычках? Это довольно глупо ...
Энди

@ Энди, когда вы пишете свою собственную базу данных SQL, не стесняйтесь реализовывать идентификаторы без учета регистра другим способом. :)
Билл Карвин

76

У меня были проблемы с этим, и это история (грустная, но правдивая):

  1. Если имя вашей таблицы в нижнем регистре, например: учетные записи, которые вы можете использовать: select * from AcCounTsи оно будет работать нормально

  2. Если имя вашей таблицы в нижнем регистре, например: accounts не удастся выполнить следующее: select * from "AcCounTs"

  3. Если у вашей таблицы смешанный регистр, например: Accounts следующее не получится: select * from accounts

  4. Если у вашей таблицы смешанный регистр, например: Accounts следующее будет работать нормально: select * from "Accounts"

Мне не нравится вспоминать такие бесполезные вещи, как это, но ты должен;)


1
То же самое для имен столбцов в выражениях where
Roland

8
5. Смешанный случай, например Accounts, потерпит неудачу, и select * from Accounts;я нахожу самую странную часть: тот же случай НЕ идентичен.
Роланд

7
Все, что нужно сделать: все имена в запросе postgres строчные, если вы не используете кавычки.
Эрндоб

1
Четвертый вариант работал для меня, хотя я не использую PHP
Sayari

2
Спасибо за выкладывание всех взаимодействий! :)
GetHacked

16

Запрос Postgres процесса отличается от других RDMS. Поставьте имя схемы в двойные кавычки перед именем таблицы, например, «SCHEMA_NAME». «SF_Bands»


7
Что добавляет ваш ответ к ранее принятому ответу, проголосовавшему 22 раза и с большим количеством деталей?
Ярослав

16

Поместите параметр dbname в строку подключения. Это работает для меня, а все остальное не удалось.

Также при выборе выберите your_schema. your_tableкак это:

select * from my_schema.your_table

1
Помогло помещение имени схемы, например my_schema.my_relation в запрос.
JoeTidee

2
Большое спасибо! Это действительно помогает мне решить проблему! Но есть ли способ, которым я могу опустить имя схемы?
Шарлотта

8

У меня была похожая проблема на OSX, но я пытался поиграть в двойные и одинарные кавычки. В вашем случае вы можете попробовать что-то вроде этого

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

4

Это действительно полезно

SET search_path TO schema,public;

Я больше разбирался в этих проблемах и узнал, как установить этот «search_path» с помощью defoult для нового пользователя в текущей базе данных.

Откройте Свойства базы данных, затем откройте Лист «Переменные» и просто добавьте эту переменную для вашего пользователя с фактическим значением.

Так что теперь ваш пользователь получит это schema_name по умолчанию, и вы можете использовать tableName без schemaName.


4

Вы должны написать имя схемы и имя таблицы в кавычках. Как показано ниже:

select * from "schemaName"."tableName";

1

Для меня проблема заключалась в том, что я использовал запрос к этой конкретной таблице во время инициализации Django. Конечно, он выдаст ошибку, потому что эти таблицы не существуют. В моем случае это был get_or_createметод в файле admin.py, который выполнялся всякий раз, когда программное обеспечение выполняло какую-либо операцию (в данном случае миграцию). Надеюсь, что это помогает кому-то.


0

Вы должны сначала добавить схему, например

SELECT * FROM place.user_place;

Если вы не хотите добавлять это во все запросы, попробуйте следующее:

SET search_path TO place;

Теперь это будет работать:

SELECT * FROM user_place;

0

Самый простой обходной путь - просто измените имя таблицы и имена всех столбцов на строчные. и ваша проблема будет решена.

Например:

  • Изменить Table_Nameна table_name и
  • Изменить ColumnNameнаcolumnname
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.