Не можна просто використовувати ім'я таблиці 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 відмінно працює
Keyslinger

Можливо, слід зазначити, що моя база даних була перенесена з MySQL
Keyslinger

Чи можете ви спробувати pg_query ($ dbconn, $ query)? Неявне підключення може спричинити важкі проблеми налагодження, а також усуне його як можливу проблему. Чи можете ви також спробувати pg_dbname ($ dbconn), щоб переконатися, що він дійсно підключений до шоуфіндера?
Брайан-Бразилія

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, що неозначені ідентифікатори рекламуються як "нечутливі до регістру". Але вони насправді не чутливі до справи, тому що спосіб, який вони реалізували, - це змусити малі регістри. Це відповідає імені таблиці лише в тому випадку, якщо ви дозволили назвати таблицю нижчим регістром під час визначення таблиці. Якщо ви використовуєте роздільники з подвійною цитатами, коли СТВОРИТИ ТАБЛИЦЮ, ви повинні використовувати роздільники, коли ви посилаєтесь на них у запитах.
Білл Карвін

Постгреси автоматично називають таблиці таблиць, якщо вони не містяться в лапках? Це досить асінін ...
Енді

@Andy, коли ви пишете власну базу даних SQL, сміливо реалізуйте ідентифікатори, що не залежать від регістрів, іншим способом. :)
Білл Карвін

76

У мене були проблеми з цим, і це історія (сумна, але правдива):

  1. Якщо у вашої назви таблиці всі великі регістри, такі як: акаунти, які ви можете використовувати: select * from AcCounTsі це буде добре

  2. Якщо назва вашої таблиці є великим регістром, наприклад: accounts Наступне не вдасться: select * from "AcCounTs"

  3. Якщо назва вашої таблиці змішане, наприклад: Accounts Не вдасться: select * from accounts

  4. Якщо назва вашої таблиці змішане з регістром типу: Accounts Наступне буде добре: select * from "Accounts"

Мені не подобається запам'ятовувати такі непотрібні речі, але вам доведеться;)


1
Те саме для назв стовпців, у яких є пункти
Roland

8
5. Змішаний випадок, як-от Accounts, не вийде, якщо select * from Accounts;я знаходжу найсмішнішу частину: той самий регістр НЕ тотожний.
Роланд

7
Все, що вам потрібно: всі імена в запиті після подрядів є малими літерами, якщо ви не використовуєте лапки.
Ерндоб

1
Четвертий варіант працював для мене, хоча я не використовую PHP
Саярі

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" шляхом декупажу для нового користувача в поточній базі даних.

Відкрийте властивості DataBase, потім відкрийте таблицю "Змінні" та просто додайте цю змінну для свого користувача з фактичним значенням.

Отже, тепер ваш користувач отримає це schema_name шляхом дефолт, і ви можете використовувати tableName без schemaName.


4

Ви повинні написати ім'я схеми та ім'я таблиці у знаку qutotation. Як нижче:

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.