2010-03-30 8 views
26

मुझे अपने SQL के ORDER BY अनुभाग में पैराम का उपयोग करने में समस्याएं आ रही हैं। यह कोई चेतावनी जारी नहीं करता है, लेकिन कुछ भी प्रिंट नहीं करता है।मैं तैयार पीडीओ स्टेटमेंट का उपयोग करके पैरा द्वारा ऑर्डर कैसे सेट करूं?

$order = 'columnName'; 
$direction = 'ASC'; 

$stmt = $db->prepare("SELECT field from table WHERE column = :my_param ORDER BY :order :direction"); 
$stmt->bindParam(':my_param', $is_live, PDO::PARAM_STR); 
$stmt->bindParam(':order', $order, PDO::PARAM_STR); 
$stmt->bindParam(':direction', $direction, PDO::PARAM_STR); 
$stmt->execute(); 

:my_param काम करता है, लेकिन नहीं :order या :direction। क्या यह आंतरिक रूप से आंतरिक रूप से बच नहीं रहा है? क्या मैं इसे एसक्यूएल में सीधे डालने में फंस गया हूं? इस तरह:

$order = 'columnName'; 
$direction = 'ASC'; 

$stmt = $db->prepare("SELECT * from table WHERE column = :my_param ORDER BY $order $direction"); 

क्या PDO::PARAM_COLUMN_NAME निरंतर या कुछ समकक्ष है?

धन्यवाद!

+0

यह भी देखें [क्या PHP पीडीओ स्टेटमेंट तालिका के नाम को पैरामीटर के रूप में स्वीकार कर सकते हैं?] (Http://stackoverflow.com/q/182287/157957) – IMSoP

उत्तर

12

मुझे नहीं लगता कि आप कर सकते हैं:

एक order by खंड में
  • उपयोग प्लेसहोल्डर
  • बाइंड स्तंभ नाम: आप केवल मूल्यों बाध्य कर सकते हैं - या चर, और उनके मूल्य तैयार बयान में इंजेक्ट किया है ।
+3

ईमानदार होने के लिए - यह ** मूल्य * बाध्य करने के लिए संभव है * (पहचानकर्ता नहीं) 'ORDER BY' खंड – zerkms

+1

में यह आंशिक रूप से सही है। आप केवल ** मूल्य ** की आपूर्ति के लिए बाध्य प्लेसहोल्डर्स का उपयोग कर सकते हैं। ** पहचानकर्ता ** (जैसे टेबल नाम, कॉलम नाम), एसक्यूएल ** कीवर्ड **, या ** मान ** के अलावा एसक्यूएल सिंटैक्स के किसी अन्य भाग की आपूर्ति के लिए बाध्य प्लेसहोल्डर्स का उपयोग करना कभी भी संभव नहीं है। (असल में, एक बाइंड प्लेसहोल्डर स्ट्रिंग शाब्दिक, एक तिथि शाब्दिक या संख्यात्मक शाब्दिक स्थान ले सकता है। अवधि। लेकिन जैसा कि ज़र्केम बताते हैं, चूंकि 'ऑर्डर बी' खंड में अभिव्यक्ति के कुछ हिस्सों के रूप में अक्षर का उपयोग करना संभव है, यह ** वास्तव में एक 'ऑर्डर बी' खंड में अभिव्यक्तियों के हिस्से के रूप में बाइंड प्लेसहोल्डर्स का उपयोग करना संभव है। – spencer7593

38

यहाँ सवाल पता चलता है कि व्यापक रूप से तैयार बयान प्यार करता था है आता नहीं चांदी की गोली, hehe :)

हाँ, आप अटक यह सीधे एसक्यूएल में डालने रहे हैं कुछ सावधानियों, निश्चित रूप से है। हर ऑपरेटर/पहचानकर्ता अपनी स्क्रिप्ट में hardcoded किया जाना चाहिए, इस तरह:

$orders=array("name","price","qty"); 
$key=array_search($_GET['sort'],$orders); 
$order=$orders[$key]; 
$query="SELECT * from table WHERE is_live = :is_live ORDER BY $order"; 

दिशा के लिए एक ही।

ध्यान दें कि बाइंडपारा कोई भाग नहीं रहा है, क्योंकि कोई भी बच निकलना आवश्यक नहीं है। यह बाध्यकारी करता है।

+0

यदि आपके पास वैध तारों की एक सरणी है और आपको '$ इनपुट = (स्ट्रिंग) $ की तरह प्राप्त करने के लिए पुनः टाइप करें इनपुट; 'से **' (स्ट्रिंग) '** आप बस 'if (in_array ($ इनपुट, $ valid_orderbys_array)) की जांच कर सकते हैं,' इसे मूल रूप से वही करना चाहिए। –

-1

यदि मुझे पूरी तरह गलत नहीं है, तो पास्कल सही है।
पीडीओ में केवल बाध्यकारी संभव मूल्यों का बाध्यकारी है, जैसा कि आपने 'my_param' पैरामीटर के साथ किया था।
हालांकि, वहाँ में किया कोई नुकसान नहीं है:

$stmt = $db->prepare("SELECT field from table WHERE column = :my_param ORDER BY ".$order ." ".$direction); 
$stmt->bindParam(':my_param', $is_live, PDO::PARAM_STR); 
$stmt->execute(); 

केवल एक चीज $order और $direction का सही एस्केपिंग होगा पर ध्यान देते हैं, लेकिन जब से तुम उन्हें मैन्युअल रूप से सेट और उपयोगकर्ता इनपुट के माध्यम से उन्हें सेट नहीं किया, मुझे लगता है कि आप सब तैयार हैं।

+0

यदि वह ऑर्डरबी कॉलम नहीं बदल रहा था और दिशा, तो मुझे उम्मीद है कि वे चर होने के कारण कोई भी बिंदु नहीं होगा। – Kzqai

4

मुझे नहीं लगता कि आप तैयार कथन के हिस्से के रूप में एएससी/डीईएससी प्राप्त कर सकते हैं, लेकिन आप जो कॉलम कर सकते हैं।

order 
    by 
     case :order 
      when 'colFoo' then colFoo 
      when 'colBar' then colBar 
      else colDefault 
     end 
     $direction 

एएससी के बाद से/DESC आप आसानी से प्रमाणित करें और hardcoded मूल्यों के रूप में उन दोनों के बीच चयन कर सकते हैं केवल दो संभावित मान है।

आप इसके लिए ईएलटी (FIELD (,,,,,,,,,,,,,,,,,,,,,,,,,) कार्यों का उपयोग भी कर सकते हैं, लेकिन फिर आदेश हमेशा एक स्ट्रिंग के रूप में किया जाएगा, भले ही यह एक संख्यात्मक कॉलम हो।

0

दुर्भाग्य से मुझे लगता है कि आप इसे तैयार बयान के साथ नहीं बना सकते हैं। यह इसे कैश करने योग्य नहीं करेगा क्योंकि विभिन्न कॉलम में ऐसे मान हो सकते हैं जिन्हें विशेष सॉर्टिंग रणनीतियों के साथ हल किया जा सके।

मानक भागने का उपयोग कर क्वेरी बनाएं और इसे सीधे निष्पादित करें।

-1

अगर कोई और स्थिति बनाएं।
हैं (ascCondion) तो मानों लेकिन हार्ड कोड आदेश द्वारा columnName एएससी बाँध
वरना
बाइंड मूल्यों लेकिन हार्ड कोड आदेश columnName DESC द्वारा

7

यह उपयोग ORDER BY खंड में तैयार बयान, दुर्भाग्य से आप की जरूरत हो सकता है नाम के कॉलम के आदेश को पास करें और टाइप के साथ PDO_PARAM_INT सेट करना आवश्यक है।

MySQL में आप इस क्वेरी के साथ कॉलम के क्रम प्राप्त कर सकते हैं:

SELECT column_name, ordinal_position FROM information_schema.columns 
WHERE table_name = 'table' and table_schema = 'database' 

PHP कोड:

$order = 2; 

$stmt = $db->prepare("SELECT field from table WHERE column = :param ORDER BY :order DESC"); 
$stmt->bindParam(':param', $is_live, PDO::PARAM_STR); 
$stmt->bindParam(':order', $order, PDO::PARAM_INT); 
$stmt->execute(); 
0

यह संभव है। आप 'ऑर्डर बाय' खंड में फ़ील्ड नाम के बजाय संख्या का उपयोग कर सकते हैं। यह 1 से शुरू होने वाली संख्या है और क्वेरी में फ़ील्ड नामों के क्रम में है। और आप एएससी या डीईएससी के लिए एक स्ट्रिंग को जोड़ सकते हैं। उदाहरण के लिए "टैब 1 ऑर्डर से col1, col2, col3 का चयन करें?" + StrDesc + "10,5 सीमित करें"। strDesc = "एएससी"/"डीईएससी"।

संबंधित मुद्दे