PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

पीडीओ अनबाउंड पैरामीटर के साथ अपवाद नहीं फेंक रहा है (और क्वेरी में कोई चर नहीं)

वह व्यवहार वर्तमान PHP (5.6.13) के साथ प्रतिलिपि प्रस्तुत करने योग्य है, और क्वेरी सर्वर को भी नहीं भेजी जाती है।

आपके मामले का वर्णन दस्तावेज़ में किया गया है के रूप में:

0 मान अपेक्षित है, 1 मान दिया गया है, और कथन विफल रहता है, false वापस किया जा रहा है। अब तक, दस्तावेज के रूप में काम करता है।

आप तर्क दे सकते हैं कि "एक त्रुटि उत्सर्जित होती है " का अर्थ यह होगा कि जब ERRMODE_EXCEPTION चालू है, एक अपवाद फेंक दिया जाएगा। यह एक तर्क है, लेकिन यह स्पष्ट नहीं है कि पीडीओ डेवलपर इससे सहमत होंगे।

अपडेट करें:

SQLCodeक्यों है? सेट नहीं?

पीडीओ स्रोत कोड को देखते हुए, विशेष रूप से static PHP_METHOD(PDOStatement, execute) जो PDO::execute() को संभालता है, आप देख सकते हैं कि सभी त्रुटियों को एक मैक्रो द्वारा नियंत्रित किया जाता है:PDO_HANDLE_STMT_ERR()

#define PDO_HANDLE_STMT_ERR()   if (strcmp(stmt->error_code, PDO_ERR_NONE)) { pdo_handle_error(stmt->dbh, stmt TSRMLS_CC); }

मुद्दा यह है कि, जब पीडीओ से किसी की अपेक्षा नहीं की जाती है, तो एक बाध्य पैरामीटर पास करते समय, क्वेरी इसे SQL इंजन में कभी नहीं बनाती है, इसलिए SQL इंजन को SQLSTATE के साथ त्रुटि की रिपोर्ट करने का अवसर कभी नहीं मिलता है

पीडीओ स्वयं एक नकली SQLSTATE नहीं बनाता है अपने आप में, कम से कम उस स्थिति में नहीं, तोstmt->error_code PDO_ERR_NONE . पर रहता है जो "00000" . है ।

यह समझ में आता है कि आप एक अपवाद को उठाना पसंद करेंगे, लेकिन फिर आपको https://bugs.php को सुझाव देना चाहिए। नेट

क्या MySQL के साथ भी ऐसा ही है?

हां, मूल व्यवहार वही है, सिवाय इसके कि MySQL ड्राइवर के साथ, prepare SQL इंजन को तुरंत भेजा जाता है, इसलिए यदि यह खराब कॉलम के कारण गलत है, तो यह पहले विफल हो जाता है और वास्तविक SQL त्रुटि के साथ। दूसरी ओर, PgSQL ड्राइवर का एक अलग कार्यान्वयन है जो इसे सर्वर-साइड prepare को स्थगित कर देता है . इस विशेष व्यवहार पर विस्तार से चर्चा की गई है PHP Postgres PDO ड्राइवर तैयार कथन का समर्थन नहीं करता है?

वैसे भी, यहाँ MySQL के साथ एक मामला है जो मेरे स्पष्टीकरण को प्रदर्शित करता है, जो है:

  • क्वेरी में 0 पैरामीटर अपेक्षित है, 1 दिया गया है
  • $stmt->execute झूठा लौटाता है
  • कोई अपवाद नहीं उठाया जाता
  • PDO::errorCode 00000 है

कोड:

$link = new PDO('mysql:dbname=' . $name . ';host=' . $host, $user, $password);
$link->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

try {
    $stmt = $link->prepare("SELECT 1");
    $rc=$stmt->execute(array(1));
   if ($rc===false)
    echo "query failed, errorCode=", $link->errorCode(), "\n";
   else
    echo "query succeeded, errorCode=", $link->errorCode(), "\n";
}
catch (PDOException $e) {
    print "A PDOException has occurred";
    print $e->getMessage();
}

परिणाम:

हुड के तहत क्या होता है कि prepare सर्वर को भेजा जाता है और सफल होता है, लेकिन execute पैरामीटर में बेमेल होने के कारण पीडीओ द्वारा चरण रद्द कर दिया गया है।

यहां एक मामला है जो इस तथ्य से भिन्न है कि क्वेरी एक गैर-मौजूदा कॉलम को संदर्भित करती है। मैं यह दिखाने के लिए एक प्रिंट जोड़ रहा हूं कि $stmt->execute कॉल भी नहीं किया जाता है, क्योंकि अपवाद $stmt->prepare . द्वारा उठाया जाता है

कोड:

$link = new PDO('mysql:dbname=' . $name . ';host=' . $host, $user, $password);
$link->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

try {
    $stmt = $link->prepare("SELECT nonexisting");
    echo "Executing query\n";
    $rc=$stmt->execute(array(1));
   if ($rc===false)
    echo "query failed, errorCode=", $link->errorCode(), "\n";
   else
    echo "query succeeded, errorCode=", $link->errorCode(), "\n";
}
catch (PDOException $e) {
  print "A PDOException has occurred";
    print $e->getMessage();
}

परिणाम:

ध्यान दें कि कैसे "क्वेरी निष्पादित करना" चरण कभी नहीं होता है, क्योंकि यह prepare है जो विफल हो जाता है, सर्वर-साइड।

निष्कर्ष

  • जब क्वेरी सर्वर को भेजी जाती है, चाहे वह तैयार हो () या निष्पादित (), और यह सर्वर है जो एक त्रुटि उत्पन्न करता है, तो हम उम्मीद कर सकते हैं कि PDOException को उठाया जाएगा।

  • जब क्वेरी निष्पादन चरण के लिए सर्वर को नहीं भेजी जाती है, तो पीडीओ निष्पादित () विफल हो सकता है (झूठा रिटर्न) लेकिन कोई अपवाद नहीं फेंका जाता है और errorCode() 00000 . पर रहता है



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. फ़ील्ड के लिए रिफैक्टर विदेशी कुंजी

  2. हेरोकू में तैनात नहीं किया जा सकता क्योंकि सर्वर ने कनेक्शन से इनकार कर दिया

  3. रेल:सरणी की सरणी में तत्व खोजने के लिए दायरे का उपयोग कैसे करें

  4. मैं PostgreSQL में कॉलम डिफ़ॉल्ट मान कैसे बदलूं?

  5. विंडोज़ पर pg_upgrad लॉग फ़ाइल में नहीं लिख सकता pg_upgrad_internal.log