मैं पीडीओ का उपयोग करके पूर्ण मान कैसे डालूं?


105

मैं इस कोड का उपयोग कर रहा हूं और मैं निराशा से परे हूं:

try {
    $dbh = new PDO('mysql:dbname=' . DB . ';host=' . HOST, USER, PASS);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
}
catch(PDOException $e)
{
    ...
}
$stmt = $dbh->prepare('INSERT INTO table(v1, v2, ...) VALUES(:v1, :v2, ...)');
$stmt->bindParam(':v1', PDO::PARAM_NULL); // --> Here's the problem

PDO::PARAM_NULL, null, '', वे सभी विफल रहते हैं और इस त्रुटि को फेंक देते हैं:

घातक त्रुटि : पैरामीटर 2 को / ऑप्ट / संदर्भ के संदर्भ में पास नहीं कर सकता ...

जवाबों:


138

मैं सिर्फ पीडीओ सीख रहा हूं, लेकिन मुझे लगता है कि आपको उपयोग करने की आवश्यकता है bindValue, नहींbindParam

bindParamसंदर्भ के लिए एक चर लेता है, और कॉलिंग के समय एक मूल्य में नहीं खींचता है bindParam। मुझे यह php डॉक्स पर एक टिप्पणी में मिला:

bindValue(':param', null, PDO::PARAM_INT);

संपादित करें: PS आपको ऐसा करने के लिए लुभाया जा सकता है bindValue(':param', null, PDO::PARAM_NULL);लेकिन यह हर किसी के लिए काम नहीं करता है (धन्यवाद रिपोर्टिंग के लिए धन्यवाद)


मुझे यकीन नहीं है कि उन दोनों के बीच अंतर है, लेकिन मैं कुछ की जांच करूंगा। धन्यवाद, आपका उत्तर भी बहुत अच्छा था।
नाचो

3
मुझे लगता है कि यह मेरा (अगर यह वास्तव में काम करता है) से बेहतर उत्तर हो सकता है
जो फिलिप्स 19

2
मुझे PDO से परेशानी थी :: MySql 5.1.53 पर PARAM_NULL, लेकिन PDO :: PARAM_INT के साथ एक अशक्त मान ने बहुत अच्छा काम किया।
विल शेवर

2
ओडिन: मुझे लगता है कि सबसे महत्वपूर्ण हिस्सा तीनों मापदंडों को पारित करना है :)। अनदेखी के सवाल में वह PDO :: PARAM_NULL मान के रूप में, टाइप करने के बजाय (और बिल्कुल भी टाइप नहीं कर रहा था) पास कर रहा था।
जेसनवॉफ

1
FYI करें: ज्यादातर मामलों में आप का उपयोग bindValue()करने के साथ पूरी तरह से ठीक हैं bindParam(); हर चीज के लिए, सिर्फ NULLमूल्य के लिए नहीं । मैं एक भी मामले के बारे में नहीं सोच सकता हूँ जहाँ आपको पैरामीटर को PHP चर के संदर्भ में बाँधने की आवश्यकता होगी - लेकिन यही bindParam()है।
low_rents

48

उपयोग करते समय bindParam() आपको एक चर में पास होना चाहिए, न कि स्थिर। तो उस लाइन से पहले आपको एक वैरिएबल बनाना होगा और उसे सेट करना होगाnull

$myNull = null;
$stmt->bindParam(':v1', $myNull, PDO::PARAM_NULL);

यदि आपने प्रयास किया तो आपको वही त्रुटि संदेश मिलेगा:

$stmt->bindParam(':v1', 5, PDO::PARAM_NULL);

आपको वह अधिकार मिल गया, मुझे बस एहसास हुआ कि मैंने इसे अपने कोड में, $ null = PDO :: PARAM_NULL से पहले किया था; धन्यवाद।
नाचो

1
यदि आप वैसे भी प्लेसहोल्डर बनाने जा रहे हैं तो इस मामले में bindValue () का उपयोग करना बेहतर होगा। bindParam () मूल रूप से एक क्वेरी को निष्पादित करने के लिए अभिप्रेत है, और फिर चर को बदलने और मापदंडों को फिर से बांधने के बिना फिर से निष्पादित करता है। bindValue () तुरंत बांधता है, bindParam () केवल निष्पादन पर।
ह्यूगो जिंक

1
मैंने पाया कि $ myNull = null लाइन में null को कम होना चाहिए। $ myNull = NULL ने काम नहीं किया।
राफेल 75

28

INTEGERकॉलम का उपयोग करते समय (जो हो सकता हैNULL ) MySQL में, पीडीओ (मेरे लिए) अनपेक्षित व्यवहार कुछ है।

यदि आप उपयोग करते हैं $stmt->execute(Array), तो आपको शाब्दिक निर्दिष्ट करना होगा NULLऔर NULLचर संदर्भ द्वारा नहीं दे सकते । तो यह काम नहीं करेगा:

// $val is sometimes null, but sometimes an integer
$stmt->execute(array(
    ':param' => $val
));
// will cause the error 'incorrect integer value' when $val == null

लेकिन यह काम करेगा:

// $val again is sometimes null, but sometimes an integer
$stmt->execute(array(
    ':param' => isset($val) ? $val : null
));
// no errors, inserts NULL when $val == null, inserts the integer otherwise

PHP 5.4.1 के साथ MySQL 5.5.15 पर यह कोशिश की


1
$ stmt-> निष्पादित (सरणी (': param' =>! खाली ($ val); $ val: null)); खाली का उपयोग करें क्योंकि खाली स्ट्रिंग के लिए आप डेटाबेस में अशक्त सेट करना चाहते हैं
शहज़ाद निज़ामनी

1
@ शेहज़ादनिज़ामनी केवल यदि स्तंभ प्रकार पूर्णांक है, जैसे उनके उदाहरण में, हाँ। लेकिन अन्यथा isset()बेहतर संबंध है NULL। एक खाली स्ट्रिंग भी एक मूल्य है।
स्टेनो

8

जिन लोगों को अभी भी समस्याएं हैं (संदर्भ द्वारा पैरामीटर 2 को पारित नहीं कर सकते हैं), शून्य मान के साथ एक चर को परिभाषित करें, न केवल पीडीओ को शून्य पास करें:

bindValue(':param', $n = null, PDO::PARAM_INT);

उम्मीद है की यह मदद करेगा।


6

मुझे भी यही समस्या थी और मैंने इस समाधान को bindParam के साथ काम करते हुए पाया:

    bindParam(':param', $myvar = NULL, PDO::PARAM_INT);

3

आप सम्मिलित करना चाहते हैं NULLकेवल जब valueहै emptyया ''है, लेकिन डालने valueजब यह उपलब्ध है।

ए) POST विधि का उपयोग करके प्रपत्र डेटा प्राप्त करता है, और उन मानों के साथ फ़ंक्शन सम्मिलित करता है।

insert( $_POST['productId'], // Will be set to NULL if empty    
        $_POST['productName'] ); // Will be to NULL if empty                                

ख) यदि कोई फ़ील्ड उपयोगकर्ता द्वारा भरा नहीं गया था, तो मूल्यांकन करता है और NULLयदि यह मामला है तो सम्मिलित करता है ।

public function insert( $productId, $productName )
{ 
    $sql = "INSERT INTO products (  productId, productName ) 
                VALUES ( :productId, :productName )";

    //IMPORTANT: Repace $db with your PDO instance
    $query = $db->prepare($sql); 

    //Works with INT, FLOAT, ETC.
    $query->bindValue(':productId',  !empty($productId)   ? $productId   : NULL, PDO::PARAM_INT); 

    //Works with strings.
    $query->bindValue(':productName',!empty($productName) ? $productName : NULL, PDO::PARAM_STR);   

    $query->execute();      
}

उदाहरण के लिए, उपयोगकर्ता पर नहीं इनपुट कुछ भी करता है, तो productNameप्रपत्र के क्षेत्र है, तो $productNameहो सकता है SETलेकिन EMPTY। तो, आपको जांच की आवश्यकता है कि क्या यह है empty(), और यदि यह है, तो डालें NULL

PHP 5.5.17 पर परीक्षण किया गया

सौभाग्य,


3
या, आप IFNULL()क्वेरी स्ट्रिंग में MySQL के फ़ंक्शन का उपयोग कर सकते हैं । इस तरह:$sql = "INSERT INTO products ( productId, productName ), VALUES ( IFNULL(:productId, NULL), IFNULL(:productName, NULL) )";
Starleaf1

मुझे स्वच्छता तुम्हारा समाधान पसंद है। मैंने अभी इसका परीक्षण किया है, लेकिन दुर्भाग्य से यह NULL के बजाय खाली स्ट्रिंग सम्मिलित करता है जब उपयोगकर्ता इनपुट पर कुछ भी नहीं लिखता है। यह सिर्फ प्राथमिकता की बात है, लेकिन मेरे पास खाली तारों के बजाय NULLs हैं।
अरियान अकोस्टा

0

इसे इस्तेमाल करे।

$stmt->bindValue(':v1', null, PDO::PARAM_NULL); // --> insert null

1
इस तरह के एक पुराने प्रश्न का उत्तर देने की कोशिश करने से पहले, आपको पहले अन्य उत्तरों को पढ़ना चाहिए। हो सकता है कि यह पहले ही उत्तर दिया जा चुका हो।
आपका कॉमन सेंस

0

अन्य उत्तरों के आधार पर लेकिन वास्तव में इस समाधान का उपयोग करने के तरीके पर थोड़ी और स्पष्टता के साथ।

यदि उदाहरण के लिए आपके पास समय मान के लिए एक खाली स्ट्रिंग है, लेकिन आप इसे एक अशक्त के रूप में सहेजना चाहते हैं:

  if($endtime == ""){
    $db->bind(":endtime",$endtime=NULL,PDO::PARAM_STR);
  }else{
    $db->bind("endtime",$endtime);
  }

ध्यान दें कि समय मान के लिए आप PARAM_STR का उपयोग करेंगे, क्योंकि समय स्ट्रिंग्स के रूप में संग्रहीत होता है।


-1

मेरे मामले में मैं उपयोग कर रहा हूं:

  • SQLite,

  • अज्ञात संख्या वाले क्षेत्रों को संभालने के लिए प्लेसहोल्डर्स के साथ तैयार किए गए बयान,

  • उपयोगकर्ता द्वारा AJAX अनुरोध भेजा गया है जहां सब कुछ एक स्ट्रिंग है और NULLमूल्य और जैसी कोई चीज नहीं है

  • मुझे सख्त NULLरूप से एस डालने की जरूरत है क्योंकि विदेशी कुंजी बाधाओं (स्वीकार्य मूल्य) का उल्लंघन नहीं करता है ।

मान लीजिए, अब उपयोगकर्ता पोस्ट के साथ भेजता है: $_POST[field1]मूल्य के साथ value1जो खाली स्ट्रिंग ""या "null"या हो सकता है "NULL"

पहले मैं बयान करता हूं:

$stmt = $this->dbh->prepare("INSERT INTO $table ({$sColumns}) VALUES ({$sValues})");

जहां {$sColumns}sth तरह है field1, field2, ...और {$sValues}मेरे प्लेसहोल्डर हैं?, ?, ...

फिर, मैं $_POSTएक कॉलम में कॉलम नामों से संबंधित अपना डेटा एकत्र करता हूं $values औरNULL s के साथ प्रतिस्थापित करता हूं :

  for($i = 0; $i < \count($values); $i++)
     if((\strtolower($values[$i]) == 'null') || ($values[$i] == ''))
        $values[$i] = null;

अब, मैं निष्पादित कर सकता हूं:

$stmt->execute($values);

और अन्य मुख्य विदेशी बाधाओं को बायपास करें।

यदि दूसरी ओर, एक खाली स्ट्रिंग अधिक समझ में आता है तो आपको यह जांचना होगा कि क्या वह क्षेत्र एक विदेशी कुंजी का हिस्सा है या नहीं (अधिक जटिल)।

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