2013-01-19 37 views
6

काम नहीं करता है मैं इस 1000 बार कहा गया है पता है, लेकिन किसी कारण मैं अपने सिर दीवार के खिलाफ टकरा करने के लिए जारी ..पीडीओ पीएचपी bindValue

यह काम करता है के लिए:

$sql = 'SELECT a.eventCode, a.eventTime, a.teamCode, a.playerCode, b.lastName, b.firstName, b.number, a.xCoord, a.yCoord, a.id '; 
$sql = $sql . 'FROM events a, players b '; 
$sql = $sql . 'WHERE a.regGUID in (' . $regGUID . ') and '; 
$sql = $sql . 'a.playerCode=b.playerCode and a.gameCode = "' . $game . '" order by a.eventTime desc, a.actionCode asc'; 
$stmt = $db->prepare($sql); 
$results = $stmt->execute(); 

यह doesn टी:

$sql = 'SELECT a.eventCode, a.eventTime, a.teamCode, a.playerCode, b.lastName, b.firstName, b.number, a.xCoord, a.yCoord, a.id '; 
$sql = $sql . 'FROM events a, players b '; 
$sql = $sql . 'WHERE a.regGUID in (:regGUID) and '; 
$sql = $sql . 'a.playerCode=b.playerCode and a.gameCode = :game order by a.eventTime desc, a.actionCode asc'; 
$stmt = $db->prepare($sql); 
$stmt->bindValue(':regGUID', $regGUID, PDO::PARAM_STR); 
$stmt->bindValue(':game', $game, PDO::PARAM_STR); 
$results = $stmt->execute(); 

मुझे क्या याद आ रही है? धन्यवाद

+0

वास्तव में एक स्ट्रिंग reggian है? – hek2mgl

+1

सुनिश्चित करें कि आप अपने डिफ़ॉल्ट चुप त्रुटि मोड से बदलकर * पीडीओ त्रुटियों को देख सकते हैं: '$ db-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_WARNING)' – eggyal

+4

पीडीओ को सेट करें [त्रुटियों पर अपवाद फेंक दें] (http : //us.php.net/manual/en/pdo.error-handling.php), देखें कि यह कुछ भी फेंकता है या नहीं। क्या '$ reggian' एक एकल GUID है, या GUID की अल्पविराम से अलग सूची है? यदि उत्तरार्द्ध, प्रत्येक GUID को एक अलग चर के रूप में बाध्य किया जाना है। – DCoder

उत्तर

5

समस्या यहाँ है:

$sql = $sql . 'WHERE a.regGUID in (:regGUID) and '; 
$stmt->bindValue(':regGUID', $regGUID, PDO::PARAM_STR); 

मुझे लगता है कि $ regGUID उद्धृत तारों की एक अल्पविराम से अलग सूची है।

प्रत्येक क्वेरी पैरामीटर केवल एक एकल स्केलर मान स्वीकार करता है। मानों की सूची नहीं है।

  1. $ regGUID स्ट्रिंग अंतर्वेशन को, भले ही आप अन्य अदिश मूल्यों के लिए पैरामीटर का उपयोग जारी रखें:

    तो आपके पास दो विकल्प। लेकिन आप अभी भी एसक्यूएल इंजेक्शन से बचने के लिए सावधान रहना चाहते हैं, इसलिए आपको $ reggin स्ट्रिंग को सही तरीके से बनाना होगा। आप पूरी स्ट्रिंग पर केवल पीडीओ :: उद्धरण() को कॉल नहीं कर सकते हैं, जो इसे यूआईआईडी और कॉमा युक्त एक उद्धृत स्ट्रिंग बना देगा। आपको यह सुनिश्चित करना होगा कि प्रत्येक यूयूआईडी स्ट्रिंग से बच निकला और व्यक्तिगत रूप से उद्धृत किया गया हो, फिर सूची को एक साथ घुमाएं और इसे आईएन क्लॉज में विभाजित करें।

    $regGUIDs = explode(',', $regGUID); 
    $regGUIDs = array_map(function ($g) { return $db->quote($g); }, $regGUIDs); 
    $regGUID = implode(',', $regGUIDs); 
    $sql = $sql . 'WHERE a.regGUID in (' . $regGUID . ') and '; 
    
  2. $ regGUID एक सरणी में explode(), और सरणी में प्रत्येक तत्व के लिए एक क्वेरी पैरामीटर जोड़ें। क्वेरी पैरामीटर प्लेसहोल्डर की गतिशील सूची को अलग करें।

    $regGUIDs = explode(',', $regGUID); 
    $params = array_fill(1, count($regGUIDs), '?'); 
    $sql = $sql . ' WHERE a.regGUID in (' . implode(',', $params) . ') and '; 
    

आप bindValue() सरणी के लिए एक पाश में कर सकता है, लेकिन यह ध्यान रखें कि अन्य पैरामीटर भी स्थिति से बंधे होने चाहिए नाम से नहीं। पीडीओ में ऐसी चीजें हैं जो आपको एक ही क्वेरी में पैरामीटर की दो अलग-अलग शैलियों को मिश्रित करने का प्रयास करते समय खुश नहीं होती हैं।

bindValue() का उपयोग करने के बजाय मैं केवल पीडीओएसटेमेंट :: execute() में पैरामीटर मानों की एक सरणी पास करता हूं, जो कि बहुत आसान है।

$paramValues = $regGUIDs; 
$paramValues[] = $game; 
$results = $stmt->execute($paramValues); 
+0

धन्यवाद .. आकर्षण की तरह काम किया! इम्प्लोड फ़ंक्शन में छोटे टाइपो सुधार में, ए के एहसास करने के लिए कुछ मिनट लग गए, इसके बजाय, एक होना चाहिए था। मेरे सिर दीवार के खिलाफ टक्कर से कम दर्द होता है! –

+0

धन्यवाद, मैंने ऊपर दिए गए मेरे उत्तर में ',' को सही किया है। मदद करने में खुशी! –

2

यह वास्तव में 1000 बार पूछा गया है।

तैयार कथन केवल स्केलर मान स्वीकार कर सकते हैं, SQL क्वेरी के मनमानी हिस्सों में नहीं।

आपको कई प्लेसहोल्डर्स का उपयोग करके IN() कथन बनाना होगा, जितना सामान आपको रखना होगा और फिर उन्हें एक-एक करके बांधना होगा।

इस कार्य को कम करने के लिए कोई कुछ सहायक कार्य का उपयोग कर सकता है।

कहो, SafeMysql library इस कोड का उपयोग के रूप में

$sql = 'SELECT * FROM events a, players b WHERE regGUID in (?a) and'; 
$sql .= ' a.playerCode=b.playerCode and a.gameCode = ?s'; 
$sql .= ' order by a.eventTime desc, a.actionCode asc'; 
$results = $db->getAll($sql,$regGUID,$game); 

नोट लिखा जा सकता है कि $regGUID एक सरणी, स्ट्रिंग नहीं और $results पहले से ही सभी का अनुरोध किया डेटा होते हैं, किसी भी आगे की प्रक्रिया के बिना होना चाहिए।

1

$regGUID की सामग्री क्या है? चूंकि आप in क्लॉज का उपयोग कर रहे हैं, इसलिए मुझे कॉमा से अलग सूची पर संदेह है।

पैरामीटर को एक चर को बाध्य करना क्वेरी में उस स्ट्रिंग को प्रतिस्थापित करने जैसा नहीं है; यह MySQL को आपके वास्तविक PHP चर का उपयोग करने के बारे में बता रहा है। तो यदि आप क्वेरी पैरामीटर में '1,2,3' जैसे स्ट्रिंग को बांधते हैं, तो यह एक स्ट्रिंग के रूप में रहता है, और संख्याओं की सूची के रूप में पुन: परिभाषित नहीं किया जाता है।

नतीजतन, अगर $regGUID"'AAA1', 'BBB2'" की तरह कुछ है, अपने पहले क्वेरी

... WHERE a.regGUID in ('AAA1', 'BBB2') ... 

हो जाता है लेकिन अपने दूसरे क्वेरी

... WHERE a.regGUID = '\'AAA1\', \'BBB2\'' ... 
1
यह कहते हुए जो एक ही है और अधिक की तरह

... WHERE a.regGUID in ('\'AAA1\', \'BBB2\'') ... 

है

जैसा कि अन्य लोगों के पास है, आप केवल एक स्केलर मान को बांध सकते हैं प्लेसहोल्डर को। तो इसका मतलब है कि आपको वास्तव में अपने IN कथन में प्रत्येक मान के लिए प्लेसहोल्डर की आवश्यकता है। मैं आमतौर पर निम्नलिखित की तरह कुछ करता हूं। ऐसा लगता है कि हालांकि मैं bindValue का उपयोग कभी नहीं, इसलिए यदि यह बातें तो नीचे दिए गए संशोधित किया जा करना पड़ सकता है mysqli तरह संदर्भ होने के लिए होने के बारे में नियम हैं:

$regGUIDPlaceholders = array(); 

// prepare the placeholders 
// assume regGUID is an array - if its a string then explode on whatever to make it an array 
foreach($regGUID as $k => $v) { 
    $placeholder = ':regGUID' . $k; 
    $regGUIDPlaceholders[$key] = $value; 
} 

// prepare the IN statememnt 
$in = sprintf('IN (%s)', implode(',', array_keys($regGUIDPlaceholders))); 

$sql = 'SELECT a.eventCode, a.eventTime, a.teamCode, a.playerCode, b.lastName, b.firstName, b.number, a.xCoord, a.yCoord, a.id '; 
$sql = $sql . 'FROM events a, players b '; 

// USE the IN statement dynamically prepared above 
$sql = $sql . 'WHERE a.regGUID '. $in . ' and '; 

$sql = $sql . 'a.playerCode=b.playerCode and a.gameCode = :game order by a.eventTime desc, a.actionCode asc'; 

$stmt = $db->prepare($sql); 

// bind each GUID to its placeholder 
foreach($regGUIDPlaceholders as $placeholder => $value) { 
    $stmt->bindValue($placeholder, $value, PDO::PARAM_STR); 
} 

$stmt->bindValue(':game', $game, PDO::PARAM_STR); 
$results = $stmt->execute();