निष्पादन
कथन को तर्कों की एक निश्चित सूची दी जानी चाहिए, इसलिए आपको और . तैयार करना होगा कथन को IF/THEN/ELSE
. में निष्पादित करें ब्लॉक करें।
IF articlesModule = 1 THEN
SET @query = ... UNION ...
PREPARE stmt FROM @query;
EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn;
ELSE
SET @query = ...; /* no UNION */
PREPARE stmt FROM @query;
EXECUTE stmt USING @searchWordIn, @searchWordIn;
END IF;
मैं MySQL संग्रहीत प्रक्रिया भाषा के सीमित दायरे में इसे हल करने का कोई तरीका नहीं जानता। मेरे लिए, संग्रहीत कार्यविधियों में गतिशील SQL का उपयोग न करने का यह एक और अच्छा कारण है।
अपनी टिप्पणी दें:
अच्छा... आप एक CASEका उपयोग कर सकते हैं कोड> कथन
IF/THEN/ELSE
. के बजाय , लेकिन आपके पास वास्तव में क्वेरी स्ट्रिंग्स के लिए 2 =128 संभावित विभिन्न मामले हैं, क्योंकि मुझे लगता है कि उन 7 मॉड्यूल में से कोई भी खोजा जा सकता है या नहीं।
एक विकल्प जो आपको क्वेरी पैरामीटर का उपयोग करने की अनुमति देगा वह है UNION
. का उपयोग करना भूल जाना , और इसके बजाय प्रक्रिया को इस तरह से लिखें कि 7 अलग-अलग SELECT
. तक चले क्वेरी करता है और उन सभी को एकाधिक परिणाम सेट . के रूप में लौटाता है . ऐसा कुछ है जो संग्रहीत प्रक्रियाओं का इरादा है। लेकिन आपको प्रत्येक परिणाम सेट को बारी-बारी से लाने के लिए अपनी PHP परत में कोड लिखना होगा। यही है, परिणाम सेट पर लूप, और उस लूप के भीतर, वर्तमान परिणाम सेट की पंक्तियों पर लूप। उदाहरण देखें PDO::nextRowset()
या mysqli::next_result()
।
नहीं, अगर आप ऐसा करते हैं तो आप सुरक्षित नहीं हैं! CALL WEBSITE_mainSearch(?)
पर एक स्ट्रिंग पास करने के लिए PHP में एक क्वेरी पैरामीटर का उपयोग करना एसक्यूएल इंजेक्शन के खिलाफ सुरक्षा के लिए बेकार है, यदि आप उस पैरामीटर मान को प्रक्रिया के अंदर किसी अन्य स्ट्रिंग में जोड़ते हैं और गतिशील एसक्यूएल पार्स-एंड-निष्पादित करते हैं। क्वेरी पैरामीटर का उपयोग करने से पैरामीटर मान "सुरक्षित" नहीं हो जाते हैं, वे केवल उन मानों को SQL पार्स चरण से अलग करते हैं।
यदि आप MySQL के अंतर्निहित फ़ंक्शन का उपयोग करते हैं तो आप सुरक्षित हैं उद्धरण ()
तारों को जोड़ते समय। उद्धरण ()
mysql_real_escape_string()
. की तरह, विशेष वर्णों से बचता है . सिवाय इसके कि यह थोड़ा अलग है, क्योंकि यह स्ट्रिंग को सीमित करने वाले एकल-उद्धरण भी उत्पन्न करता है, जैसे पीडीओ::उद्धरण ()
करता है।
SET @query = CONCAT(@query, 'SELECT blockName AS itemName, blockPath AS seoName,
blockID AS itemID, MATCH(blockName, blockBody) AGAINST (',
QUOTE(searchWordIn), ') AS relevance, \'block\' AS itemType
FROM content_blocks WHERE MATCH(blockName, blockBody) AGAINST (',
QUOTE(searchWordIn),')') ;
अपडेट करें:एक और विकल्प:UNION
. का उपयोग करें अधिक सबक्वेरी जोड़ने के लिए, और मॉड्यूल की गिनती रखने के लिए। फिर एक CASE
. का उपयोग करें संचित गणना के आधार पर विभिन्न मापदंडों के साथ तैयार क्वेरी को निष्पादित करने के लिए।
SET @n = 0;
IF articlesModule = 1 THEN
SET @query = ... UNION ...
SET @n = @n+1;
END IF;
IF newsModule = 1 THEN
SET @query = ... UNION ...
SET @n = @n+1;
END IF;
... and similar for the other 5 modules ...
PREPARE stmt FROM @query;
CASE @n
WHEN 1:
EXECUTE stmt USING @searchWordIn, @searchWordIn;
WHEN 2:
EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn;
WHEN 3:
EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
@searchWordIn, @searchWordIn;
WHEN 4:
EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
@searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn;
WHEN 5:
EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
@searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
@searchWordIn, @searchWordIn;
WHEN 6:
EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
@searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
@searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn;
WHEN 7:
EXECUTE stmt USING @searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
@searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
@searchWordIn, @searchWordIn, @searchWordIn, @searchWordIn,
@searchWordIn, @searchWordIn;
END;