2012-07-18 5 views
5

मैं संकलक रिपोर्ट "PL/SQL के रूप में ओरेकल कोड के इस हिस्से complile करने में असमर्थ हूँ: ORA-00942: टेबल या दृश्य मौजूद नहीं है "जब एक Oracle PL/SQL ईमेल भीतर लूप के लिए एक चल कैसे एक तालिका नाम के लिए एक चर का उपयोग करने के लिए भेज

ओरेकल तालिका मौजूद है, लेकिन इस प्रक्रिया के आधार पर के लिए लूप प्रक्रिया के लिए एक तालिका नाम से गुजरना होगा" ORDER_ID "पैरामीटर। मैं स्कीमा के भीतर काम कर रहा हूं जहां तालिका मौजूद है इसलिए मैं स्कीमा नाम को संबोधित नहीं कर रहा हूं।

उदाहरण: TEMP_TBL_123 डेटाबेस में मौजूद है और 123 के ऑर्डर_आईडी को पास करके मैं तालिका नाम "TEMP_TBL_123" रखने के लिए परिवर्तनीय TMP_TBL_NM का उपयोग करने का प्रयास कर रहा हूं।

.............................................. ...

CREATE OR REPLACE PROCEDURE EMAIL_DEPT_BLAST_TEST (SUBJECT VARCHAR2,MAIL_FROM VARCHAR2, MAIL_TO VARCHAR2, 
               L_MESSAGE VARCHAR2, L_MESSAGE2 VARCHAR2, ORDER_ID NUMBER) 
IS 
MAIL_HOST VARCHAR2(30):='XX.XX.XX.XX'; 
MAIL_CONN UTL_SMTP.CONNECTION; 
TMP_TBL_NM VARCHAR2(30); 

BEGIN 

TMP_TBL_NM := 'TEMP_TBL_' || ORDER_ID; 

MAIL_CONN := UTL_SMTP.OPEN_CONNECTION(MAIL_HOST, 25); 
UTL_SMTP.HELO(MAIL_CONN, MAIL_HOST); 
UTL_SMTP.MAIL(MAIL_CONN,'[email protected]'); 
UTL_SMTP.RCPT(MAIL_CONN, MAIL_TO); 
UTL_SMTP.OPEN_DATA(MAIL_CONN); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, 'Date: '||to_char(trunc(SYSDATE))||utl_tcp.crlf); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, 'From: '|| mail_from ||utl_tcp.crlf); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, 'To: '|| mail_to || utl_tcp.crlf); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, 'Subject: '||subject||utl_tcp.crlf); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, UTL_TCP.CRLF); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, ''|| L_MESSAGE || UTL_TCP.CRLF); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, UTL_TCP.CRLF); 

UTL_SMTP.WRITE_DATA(MAIL_CONN, 'Order details:' || UTL_TCP.crlf); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, 'Quantity - Location ID - Address' || UTL_TCP.crlf); 

BEGIN 
    FOR I IN (SELECT LOCATION_ID, TRIM(TO_CHAR(COUNT(*),'9,999')) AS QUANTITY FROM TMP_TBL_NM GROUP BY LOCATION_ID) 
    LOOP 
    UTL_SMTP.WRITE_DATA(MAIL_CONN, I.QUANTITY || ' - '); 
    UTL_SMTP.WRITE_DATA(MAIL_CONN, I.LOCATION_ID || ' '); 
    UTL_SMTP.WRITE_DATA(MAIL_CONN,UTL_TCP.CRLF); 
    END LOOP; 
END; 

UTL_SMTP.WRITE_DATA(MAIL_CONN, L_MESSAGE2 || UTL_TCP.CRLF); 

UTL_SMTP.WRITE_DATA(MAIL_CONN,UTL_TCP.CRLF); 
UTL_SMTP.CLOSE_DATA(MAIL_CONN); 
UTL_SMTP.QUIT(MAIL_CONN); 

END SCT_CNTS_EMAIL_DEPT_BLAST_TEST; 

उत्तर

0

एक ही तरीका है इस तरह SQL कथन में चर पारित करने के लिए dynamic sql के रूप में क्वेरी चलाने के लिए किया जाएगा।

DECLARE 
    query_output SYS_REFCURSOR; 
    query_statement VARCHAR2(1000); 
BEGIN 
    query_statement := 'SELECT LOCATION_ID, TRIM(TO_CHAR(COUNT(*),'9,999')) AS QUANTITY FROM ' || TMP_TBL_NM || ' GROUP BY LOCATION_ID'; 
    execute immediate query_statement using out query_output; 
    .... 
END 

अब आप एक कर्सर है, सामग्री, गिनती से अधिक पाश लाने और बाकी सब कुछ करते हैं

+2

"चर पारित करने का एकमात्र तरीका .. गतिशील एसक्यूएल होगा"। वास्तव में सच नहीं है। एक पीएल/एसक्यूएल वैरिएबल को इनलाइन एसक्यूएल कथन में कहीं भी एम्बेड किया जा सकता है, जहां भी आप स्ट्रिंग या नंबर जैसे शाब्दिक मूल्य डाल सकते हैं। गतिशील एसक्यूएल के बिना आप क्या नहीं कर सकते हैं, एक * पहचान * के स्थान पर एक चर का उपयोग करते हैं, जैसे टेबल नाम या कॉलम नाम। ऐसा इसलिए है क्योंकि एसक्यूएल कथन पार्स किए जाने पर पहचानकर्ता नामों को जाना जाना चाहिए, जो परिवर्तनीय मानों से पहले होते हैं। –

5

मैं बहुत किस्मत जॉन बनाने नहीं था:

आपका कोड की तरह कुछ हो सकता है उदाहरण काम यहां कुछ ऐसा है जो करता है:

DECLARE 
    C SYS_REFCURSOR; 
    stmt VARCHAR2(1000); 
    tmp_tbl_nm VARCHAR2(64) := 'USER_TABLES'; 
    the_name VARCHAR2(64); 
BEGIN 
    stmt := 'SELECT table_name FROM ' || TMP_TBL_NM || ' ORDER BY 1'; 
    OPEN C FOR stmt; 
    LOOP 
     FETCH C INTO the_name; 
     EXIT WHEN C%NOTFOUND; 
     dbms_output.put_line(the_name); 
    END LOOP; 
END; 
/
CONTINENT 
COUNTRY 
COUNTRYINFOIMPORT 
COUNTRY_LANGUAGE 
GEONAME 
LANGUAGE 

PL/SQL procedure successfully completed. 

SQL> 

मुझे नहीं लगता कि आप एक सटीक तत्काल कथन के साथ एक कर्सर वापस कर सकते हैं। This documentation page, दूसरा अनुच्छेद, ऐसा नहीं लगता है। किसी भी दर पर, आपको इसकी आवश्यकता नहीं है, केवल ओपन - फॉर सिंटैक्स का उपयोग करें।

1

कारण है कि आप PL/SQL मिलती है: ORA-00942 है क्योंकि आपके मूल कोड में संकलक एक मेज "TMP_TBL_NM" कहा जाता है के लिए लग रही है। यह आपकी स्कीमा में मौजूद नहीं है और वास्तव में आपके पीएल/एसक्यूएल के भीतर तालिका का नाम धारण करने वाला एक चर है।

मैं पिछले एक जवाब अनुकूल की स्वतंत्रता ले लिया और अपने जवाब के लिए एक बदलाव के साथ आने के लिए गतिशील एसक्यूएल का एक सा इस्तेमाल किया।

CREATE OR REPLACE PROCEDURE EMAIL_DEPT_BLAST_TEST (SUBJECT VARCHAR2,MAIL_FROM VARCHAR2, MAIL_TO VARCHAR2, 
               L_MESSAGE VARCHAR2, L_MESSAGE2 VARCHAR2, ORDER_ID NUMBER) 
IS 
MAIL_HOST VARCHAR2(30):='XX.XX.XX.XX'; 
MAIL_CONN UTL_SMTP.CONNECTION; 
TMP_TBL_NM VARCHAR2(30); 

BEGIN 

TMP_TBL_NM := 'TEMP_TBL_' || ORDER_ID; 

MAIL_CONN := UTL_SMTP.OPEN_CONNECTION(MAIL_HOST, 25); 
UTL_SMTP.HELO(MAIL_CONN, MAIL_HOST); 
UTL_SMTP.MAIL(MAIL_CONN,'[email protected]'); 
UTL_SMTP.RCPT(MAIL_CONN, MAIL_TO); 
UTL_SMTP.OPEN_DATA(MAIL_CONN); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, 'Date: '||to_char(trunc(SYSDATE))||utl_tcp.crlf); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, 'From: '|| mail_from ||utl_tcp.crlf); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, 'To: '|| mail_to || utl_tcp.crlf); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, 'Subject: '||subject||utl_tcp.crlf); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, UTL_TCP.CRLF); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, ''|| L_MESSAGE || UTL_TCP.CRLF); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, UTL_TCP.CRLF); 

UTL_SMTP.WRITE_DATA(MAIL_CONN, 'Order details:' || UTL_TCP.crlf); 
UTL_SMTP.WRITE_DATA(MAIL_CONN, 'Quantity - Location ID - Address' || UTL_TCP.crlf); 

TYPE ItemRec IS RECORD (
loc_id NUMBER, 
qty_cnt NUMBER); 

TYPE ItemSet IS TABLE OF ItemRec; 
all_items ItemSet; 

BEGIN 

    stmt := 'SELECT LOCATION_ID, TRIM(TO_CHAR(COUNT(*),'9,999')) AS QUANTITY FROM '||TMP_TBL_NM ||' GROUP BY LOCATION_ID'; 
    EXECUTE IMMEDIATE stmt 
    BULK COLLECT 
    INTO all_items; 

    FOR i IN all_items.FIRST..all_items.LAST 
    LOOP 
     UTL_SMTP.WRITE_DATA(MAIL_CONN, I.QUANTITY || ' - '); 
     UTL_SMTP.WRITE_DATA(MAIL_CONN, I.LOCATION_ID || ' '); 
     UTL_SMTP.WRITE_DATA(MAIL_CONN,UTL_TCP.CRLF); 
    END LOOP; 
END; 

UTL_SMTP.WRITE_DATA(MAIL_CONN, L_MESSAGE2 || UTL_TCP.CRLF); 

UTL_SMTP.WRITE_DATA(MAIL_CONN,UTL_TCP.CRLF); 
UTL_SMTP.CLOSE_DATA(MAIL_CONN); 
UTL_SMTP.QUIT(MAIL_CONN); 

END SCT_CNTS_EMAIL_DEPT_BLAST_TEST; 
संबंधित मुद्दे