2010-05-02 5 views
23

मैं अलग टेबल के बंद का चयन करने के लिए इस sproc उपयोग करने के लिए संग्रहीत प्रक्रिया मेरी mysql में कोई तालिका नाम पारित करने के लिए कोशिश कर रहा हूँ, लेकिन यह काम नहीं कर रहा ...mysql sproc में तालिका नाम के लिए एक चर का उपयोग

यह क्या है मैं "की कोशिश कर रहा हूँ:

CREATE PROCEDURE `usp_SelectFromTables`(
IN TableName varchar(100) 
) 
BEGIN 
     SELECT * FROM @TableName; 
END 

मैं भी w/ओ @ चिह्न यह कोशिश की है और कहा कि सिर्फ मुझसे कहता है कि TableName मौजूद नहीं है ... मुझे पता है जो :)

उत्तर

12

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

कुछ डीबीएमएस ने प्रक्रिया समर्थन को संग्रहीत किया है जो आपको एक एसक्यूएल स्ट्रिंग बनाने की अनुमति देगा और फिर 'तैयार' या 'निष्पादित तत्काल' या इसी तरह के संचालन का उपयोग करके उसके साथ काम करेगा। नोट, हालांकि, आप एसक्यूएल इंजेक्शन हमलों के लिए अचानक कमजोर हैं - कोई भी जो आपकी प्रक्रिया को निष्पादित कर सकता है, उसके बाद, एसक्यूएल को निष्पादित करने के लिए, कुछ हद तक नियंत्रित करने में सक्षम होता है।

44
SET @cname:='jello'; 
SET @vname:='dwb'; 
SET @sql_text = concat('select concept_id,concept_name,',@vname,' from enc2.concept a JOIN enc2.ratings b USING(concept_id) where concept_name like (''%',@cname,'%'') and 3 is not null order by 3 asc'); 

PREPARE stmt FROM @sql_text; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 
+0

वाह, क्या एक ब्रिल विशाल रास्ता! –

12

एक अतिरिक्त बिट जिससे मुझे समस्याएं आईं।

मैं क्वेरी के नाम से तालिका में नाम और फ़ील्ड को गतिशील रूप से सेट करना चाहता था क्योंकि मैं पूछता हूं, लेकिन मैं क्वेरी के भीतर उस क्वेरी का परिणाम @a में संग्रहीत करना चाहता था।

@a को concat में अक्षर को डालने के बजाय, आपको इसे स्ट्रिंग टेक्स्ट के हिस्से के रूप में शामिल करने की आवश्यकता है। @sql_text2 उपयोग @a में एक वास्तविक चर के रूप में

') INTO @a FROM '

तब:

delimiter // 

CREATE PROCEDURE removeProcessed(table_name VARCHAR(255), keyField VARCHAR(255), maxId INT, num_rows INT) 

BEGIN 
    SET @table_name = table_name; 
    SET @keyField = keyField; 
    SET @maxId = maxId; 
    SET @num_rows = num_rows; 

    SET @sql_text1 = concat('SELECT MIN(',@keyField,') INTO @a FROM ',@table_name); 
    PREPARE stmt1 FROM @sql_text1; 
    EXECUTE stmt1; 
    DEALLOCATE PREPARE stmt1; 

    loop_label: LOOP 
    SET @sql_text2 = concat('SELECT ',@keyField,' INTO @z FROM ',@table_name,' WHERE ',@keyField,' >= ',@a,' ORDER BY ',@keyField,' LIMIT ',@num_rows,',1'); 
    PREPARE stmt2 FROM @sql_text2; 
    EXECUTE stmt2; 
    DEALLOCATE PREPARE stmt2; 

    ...Additional looping code... 

    END LOOP; 
END 
// 

delimiter ; 

तो @sql_text1 में क्वेरी का परिणाम @a को स्ट्रिंग के भीतर का उपयोग कर आवंटित

,' WHERE ',@keyField,' >= ', @a ,' ORDER BY '

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