बस 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());

यह निम्न त्रुटि उत्पन्न करता है:

क्वेरी विफल: ERROR: संबंध "sf_bands" मौजूद नहीं है

सभी उदाहरणों में मैं पा सकता हूं कि किसी को यह कहते हुए त्रुटि मिलती है कि संबंध मौजूद नहीं है, ऐसा इसलिए है क्योंकि वे अपने टेबल के नाम में अपरकेस अक्षरों का उपयोग करते हैं। मेरे टेबल का नाम अपरकेस अक्षर नहीं है। क्या डेटाबेस नाम सहित, बिना मेरी तालिका को क्वेरी करने का एक तरीका है showfinder.sf_bands?


2
क्या आप सुनिश्चित हैं कि sf_bands टेबल मौजूद है? क्या showfinder.sf_bands काम करता है?
ब्रायन-ब्राज़ील

1
showfinder.sf_bands पूरी तरह से काम करता है
Keyslinger

शायद मुझे यह ध्यान रखना चाहिए कि मेरा डेटाबेस MySQL
Keyslinger

क्या आप pg_query ($ dbconn, $ क्वेरी) आज़मा सकते हैं? अंतर्निहित कनेक्शन हार्ड-टू-डीबग समस्याओं का कारण बन सकता है, साथ ही साथ इसे संभावित समस्या के रूप में समाप्त कर सकता है। क्या आप यह सुनिश्चित करने के लिए pg_dbname ($ dbconn) को भी आज़मा सकते हैं कि यह वास्तव में शोफाइंडर से जुड़ा है?
ब्रायन-ब्राज़ील

1
+1 यह उल्लेख करने के लिए कि अपरकेस अक्षर समस्या हैं। मैंने एक घंटे बिताए यह पता लगाने की कोशिश कर रहा हूं कि मैं पोस्टग्रेक्यूएल में एक भी मेज से चयन क्यों नहीं कर सका। कितना भयानक कार्यक्रम है।
ब्रेन २२

जवाबों:


298

मैंने जो पढ़ा है, उससे इस त्रुटि का मतलब है कि आप तालिका के नाम को सही ढंग से संदर्भित नहीं कर रहे हैं। एक सामान्य कारण यह है कि तालिका को मिश्रित-मामले की वर्तनी के साथ परिभाषित किया गया है, और आप इसे सभी निचले मामलों के साथ क्वेरी करने का प्रयास कर रहे हैं।

दूसरे शब्दों में, निम्नलिखित विफल रहता है:

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 भी देखें


उफ़, मुझे माफ़ कर दो। मेरे कहने का मतलब है कि मेरे टेबल के नाम में कोई बड़ा अक्षर नहीं है, न कि मेरे डेटाबेस का नाम।
कीसलिंगर

13
ऐसा प्रतीत होता है कि यदि आप टाइप SELECT * FROM SF_Bandsकरते हैं तो भी यह विफल हो जाएगा, क्योंकि Postgres आपके लिए उस तालिका नाम को कम करने का निर्णय लेता है। अजीब ...
रोमन स्टार्कोव

3
@romkyns: हाँ, यह वास्तव में आरडीबीएमएस ब्रांडों में बहुत आम है, कि बिना पहचान वाले विज्ञापनदाताओं को "केस-असंवेदनशील" के रूप में विज्ञापित किया जाता है। लेकिन वे वास्तव में असंवेदनशील नहीं हैं क्योंकि जिस तरह से उन्होंने लागू किया है वह लोअरकेस को मजबूर करने के लिए है। यह तालिका के नाम से मेल खाता है, यदि आपने तालिका को परिभाषित करते समय तालिका के नाम को नीचा दिखाया है। यदि आप डबल-टेबल सीमांकक का उपयोग करते हैं, तो जब आप बनाते हैं, तो आपको प्रश्नों में संदर्भ देते समय परिसीमन का उपयोग करना चाहिए।
बिल कारविन

यदि वे उद्धरणों में नहीं हैं तो पोस्टग्रेज स्वचालित रूप से टेबल के नाम को कम कर देता है? यह बहुत सुंदर है ...
एंडी

@ और, जब आप अपना स्वयं का SQL डेटाबेस लिखते हैं, तो केस-असंवेदनशील पहचानकर्ताओं को किसी अन्य तरीके से लागू करने के लिए स्वतंत्र महसूस करें। :)
बिल करविन

76

मुझे इसके साथ समस्या थी और यह कहानी है (दुखद लेकिन सच):

  1. यदि आपकी तालिका का नाम सभी निचले मामलों की तरह है: आप जिन खातों का उपयोग कर सकते हैं: select * from AcCounTsऔर यह ठीक काम करेगा

  2. यदि आपके टेबल का नाम सभी निचले मामलों की तरह है: accounts निम्नलिखित विफल हो जाएगा: select * from "AcCounTs"

  3. यदि आपके टेबल का नाम मिश्रित मामला है जैसे: Accounts निम्नलिखित विफल हो जाएगा: select * from accounts

  4. यदि आपके टेबल का नाम मिश्रित मामला है जैसे: Accounts निम्नलिखित काम करेगा: select * from "Accounts"

मैं इस तरह बेकार सामान को याद नहीं करना चाहता, लेकिन आपको करना है;)


1
कॉलम-नामों के लिए समान-खंड में समान
रोलाण्ड

8
5. मिश्रित मामला, जैसे Accounts, select * from Accounts;मैं सबसे अजीब हिस्सा ढूंढने में असफल हो जाऊंगा: समान-मामला समान नहीं है।
रोलैंड

7
वहाँ यह सब है: जब तक आप उद्धरण का उपयोग नहीं करते तब तक पोस्टग्रैड क्वेरी में सभी नाम कम होते हैं।
एरंडोब

1
चौथा विकल्प मेरे लिए काम करता है, हालांकि मैं
Sayari

2
सभी इंटरैक्शन को बाहर करने के लिए धन्यवाद! :)
GetHacked 16

16

अन्य RDMS से भिन्न प्रक्रिया क्वेरी को पोस्ट करता है। अपनी तालिका के नाम से पहले दोहरे उद्धरण में स्कीमा नाम रखें, जैसे "SCHEMA_NAME"। "SF_Bands"


7
आपके द्वारा पहले स्वीकार किए गए उत्तर में 22 बार और बहुत सारे विवरणों के साथ आपका उत्तर क्या कहता है?
यारोस्लाव

16

अपने कनेक्शन स्ट्रिंग में dbname पैरामीटर लगाएं। यह मेरे लिए काम करता है जबकि बाकी सब विफल रहा।

चयन करते समय भी, निर्दिष्ट करें your_schemayour_tableइस तरह:

select * from my_schema.your_table

1
स्कीमा नाम को अंदर लाना, जैसे my_schema.my_relation में क्वेरी मदद की।
जोतिडे

2
आपका बहुत बहुत धन्यवाद! यह reall मुझे समस्या को हल करने में मदद करता है! लेकिन क्या कोई ऐसा तरीका है जिससे मैं योजना के नाम को छोड़ सकता हूं?
शार्लोट

8

मुझे OSX पर इसी तरह की समस्या थी, लेकिन डबल और सिंगल कोट्स के साथ खेलने की कोशिश की। आपके मामले के लिए, आप कुछ इस तरह की कोशिश कर सकते हैं

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

4

यह वास्तव में सहायक है

SET search_path TO schema,public;

मैंने इस मुद्दे को और अधिक खोद लिया, और वर्तमान डेटाबेस में एक नए उपयोगकर्ता के लिए डीफ़ॉल्ट द्वारा इस "search_path" को सेट करने के तरीके के बारे में पता लगाया।

डेटाबेस गुण खोलें फिर शीट "वेरिएबल्स" खोलें और वास्तविक मूल्य के साथ अपने उपयोगकर्ता के लिए बस इस चर को जोड़ें।

तो अब आपके उपयोगकर्ता को यह स्कीमा_नाम डिफॉल्ट के द्वारा मिलेगा और आप स्कीमनाम के बिना टेबलनेम का उपयोग कर सकते हैं।


4

आपको क्यूटोटेशन मार्क में स्कीमा नाम और टेबल का नाम लिखना होगा। नीचे के अनुसार:

select * from "schemaName"."tableName";

1

मेरे लिए समस्या यह थी, कि मैंने उस विशेष तालिका में एक क्वेरी का उपयोग किया था, जबकि Django को इनिशियलाइज़ किया गया था। बेशक यह तब एक त्रुटि फेंक देगा, क्योंकि उन तालिकाओं का अस्तित्व नहीं था। मेरे मामले में, यह एक व्यवस्थापक get_or_createफ़ाइल के भीतर एक विधि थी, जिसे तब भी निष्पादित किया गया था जब सॉफ्टवेयर किसी भी तरह का ऑपरेशन चलाता था (इस मामले में माइग्रेशन)। आशा है कि किसी की मदद करता है।


0

आपको स्कीमा को पहले जोड़ना होगा

SELECT * FROM place.user_place;

यदि आप सभी प्रश्नों में इसे जोड़ना नहीं चाहते हैं तो यह प्रयास करें:

SET search_path TO place;

अब यह काम करेगा:

SELECT * FROM user_place;

0

सबसे आसान वर्कअराउंड टेबल का नाम और सभी कॉलम नामों को लोअरकेस में बदलना है और आपका मुद्दा हल हो जाएगा।

उदाहरण के लिए:

  • बदलें Table_Nameकरने के लिए table_name और
  • बदलें ColumnNameकरने के लिएcolumnname
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.