2016-05-13 8 views
9

मेरे एसक्यूएल इस तरह दिखता है:सिद्धांत - एसक्यूएल को सरणी कैसे बांधें?

$sql = "select * from user where id in (:userId) and status = :status"; 

$em = $this->getEntityManager(); 
$stmt = $em->getConnection()->prepare($sql); 
$stmt->bindValue(':userId', $accounts, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY); 
$stmt->bindValue(':status', 'declined'); 
$stmt->execute(); 

$result = $stmt->fetchAll(); 

लेकिन यह रिटर्न:

An exception occurred while executing (...)

with params [[1,2,3,4,5,6,7,8,11,12,13,14], "declined"]

Notice: Array to string conversion

मैं नहीं कर सकते हैं उपयोगकर्ता queryBuilder क्योंकि मेरा असली एसक्यूएल अधिक जटिल है (पूर्व चयन में शामिल हो गए शामिल, यूनियनों और इतने पर।)

+0

क्या आप foreach का उपयोग कर सकते हैं? 'foreach ($ $ = $ $ val के रूप में $ खातों) {$ stmt-> bindValue (': userId', $ val); } ' – pes502

उत्तर

8

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

सौभाग्य से, डीबीएएल ने आपको कवर किया है। आप बस बांध या तैयार नहीं करते हैं। http://doctrine-orm.readthedocs.io/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#list-of-parameters-conversion

आपके मामले में यह कुछ ऐसा दिखाई देगा: इसके बाद के संस्करण कोड अपरीक्षित है, लेकिन आप विचार मिलना चाहिए

$sql = "select * from user where id in (?) and status = ?"; 
$values = [$accounts,'declined']; 
$types = [Connection::PARAM_INT_ARRAY, \PDO::PARAM_STRING]; 
$stmt = $conn->executeQuery($sql,$values,$types); 
$result = $stmt->fetchAll(); 

मैनुअल एक उदाहरण है।

+0

ठीक नहीं है लेकिन इस स्थिति में मुझे सही क्रम में डेटा को बाध्य करने के लिए सावधान रहना होगा :(यह "अच्छा नहीं है": \ – breq

+0

मैं चिंता को समझता हूं और नामित पैरामीटर अच्छे हैं लेकिन इसके बारे में सोचें, आपके पास केवल दो पैरामीटर हैं। उन्हें क्रम में रखना मुश्किल नहीं है। बड़ी संख्या में पैरामीटर के साथ प्रश्नों से निपटने पर, मैं एसक्यूएल उत्पन्न करने के लिए डबल क्वेरी बिल्डर का उपयोग करता हूं और मूल रूप से मेरे $ मूल्य सरणी में मान जोड़ता हूं मैं साथ जाता हूं। इसलिए जब आप इसका इस्तेमाल करते हैं तो यह इतना बुरा नहीं होता है। और यह आपको यह तय करने से बचाता है कि पैरामीटर को पहले स्थान पर क्या नामित किया जाना चाहिए। नामकरण हमेशा कठिन होता है। – Cerad

+0

लेकिन एमयू असली एसक्यूएल अधिक जटिल है http: // pastebin।com/1JiRHFdc, कोई विचार यह 'सही' कैसे करें? इसमें अधिक चर शामिल होंगे और जहां उपयोगकर्ता अधिक फ़िल्टर परिणाम – breq

-1

आप उन्हें एक सरणी में रैप करने के लिए की जरूरत है

$stmt->bindValue(':userId', array($accounts), array(\Doctrine\DBAL\Connection::PARAM_INT_ARRAY)); 

http://doctrine-dbal.readthedocs.io/en/latest/reference/data-retrieval-and-manipulation.html#list-of-parameters-conversion

संपादित

मैं और अधिक विस्तार से बताया जाना चाहिए था। आप इस तरह की सरणी को बाध्य नहीं कर सकते हैं, दस्तावेज़ों में उदाहरण के रूप में सीधे एसक्यूएल निष्पादन तैयार न करें।

$stmt = $conn->executeQuery('SELECT * FROM articles WHERE id IN (?)', 
array(array(1, 2, 3, 4, 5, 6)), 
array(\Doctrine\DBAL\Connection::PARAM_INT_ARRAY)); 

You cannot bind an array of values into a single prepared statement parameter

+1

मुझे ऐसा नहीं लगता ... 'चेतावनी: पीडीओएसटेमेंट :: बाइंडवैल्यू() पैरामीटर 3 को पूर्णांक होने की उम्मीद करता है, सरणी दिया गया है। मैं 'तैयार' विधि का उपयोग कर रहा हूं, 'executeQuery' – breq

0

आप :param वाक्य रचना जहां आदेश कोई फर्क नहीं पड़ता पर कायम करना चाहते हैं, तो आप अतिरिक्त काम का एक सा करना है, लेकिन मैं आपको मापदंडों बाध्य करने के लिए एक आसान तरीका दिखाएंगे:

// store all your parameters in one array 
$params = array(
    ':status' => 'declined' 
); 

// then, using your arbitrary array of id's ... 
$array_of_ids = array(5, 6, 12, 14); 

// ... we're going to build an array of corresponding parameter names 
$id_params = array(); 
foreach ($array_of_ids as $i => $id) { 
    // generate a unique name for this parameter 
    $name = ":id_$i"; // ":id_0", ":id_1", etc. 

    // set the value 
    $params[$name] = $id; 

    // and keep track of the name 
    $id_params[] = $name; 
} 

// next prepare the parameter names for placement in the query string 
$id_params = implode(',', $id_params); // ":id_0,:id_1,..." 
$sql = "select * from user where id in ($id_params) and status = :status"; 

इस मामले में हम साथ अंत: "select * from user where id in (:id_0,:id_1,:id_2,:id_3) and status = :status"

// now prepare your statement like before... 
$stmt = $em->getConnection()->prepare($sql); 

// ...bind all the params in one go... 
$stmt->execute($params); 

// ...and get your results! 
$result = $stmt->fetchAll(); 

यह दृष्टिकोण भी तार की एक सरणी के साथ काम करेंगे।

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