2009-04-13 15 views
13

के माध्यम से फ़ंक्शन बनाएं I Python में MySQLdb lib का उपयोग करने में बहु-कथन फ़ंक्शन या प्रक्रिया को कैसे परिभाषित किया जा सकता है?MySQLdb

उदाहरण:

import MySQLdb 

db = MySQLdb.connect(db='service') 

c = db.cursor() 

c.execute("""DELIMITER // 
CREATE FUNCTION trivial_func (radius float) 
    RETURNS FLOAT 

    BEGIN 
    IF radius > 1 THEN 
     RETURN 0.0; 
    ELSE 
     RETURN 1.0; 
    END IF; 
END // 

DELIMITER ;""") 

निम्नलिखित में से कौन ट्रैस बैक बनाता है:

Traceback (most recent call last): 
    File "proof.py", line 21, in <module> 
    DELIMITER ;""") 
    File "build/bdist.macosx-10.5-i386/egg/MySQLdb/cursors.py", line 173, in execute 
    File "build/bdist.macosx-10.5-i386/egg/MySQLdb/connections.py", line 35, in defaulterrorhandler 
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER //\nCREATE FUNCTION trivial_func (radius float) \n RETURNS FLOAT\n\n ' at line 1") 

मैं एक mysql खोल ग्राहक में सीधे ही एसक्यूएल कॉपी करते हैं, यह उम्मीद

उत्तर

17

DELIMITER आदेश के रूप में काम करता है एक MySQL शैल क्लाइंट बनाया गया है, और यह केवल उस प्रोग्राम (और MySQL क्वेरी ब्राउज़र) द्वारा पहचाना जाता है। यदि आप किसी API के माध्यम से सीधे SQL कथन निष्पादित करते हैं तो DELIMITER का उपयोग करना आवश्यक नहीं है।

DELIMITER का उद्देश्य CREATE FUNCTION कथन की समाप्ति के बारे में अस्पष्टता से बचने में आपकी सहायता करना है, जब कथन में अर्धविराम वर्ण हो सकते हैं। शैल क्लाइंट में यह महत्वपूर्ण है, जहां डिफ़ॉल्ट रूप से अर्धविराम एक SQL कथन को समाप्त करता है। फ़ंक्शन (या ट्रिगर या प्रक्रिया) के शरीर को सबमिट करने के लिए आपको कथन टर्मिनेटर को किसी अन्य चरित्र में सेट करने की आवश्यकता है।

CREATE FUNCTION trivial_func (radius float) 
    RETURNS FLOAT 

    BEGIN 
    IF radius > 1 THEN 
     RETURN 0.0; <-- does this semicolon terminate RETURN or CREATE FUNCTION? 
    ELSE 
     RETURN 1.0; 
    END IF; 
END 

के बाद से एपीआई आम तौर पर आप एक समय में एक SQL विवरण प्रस्तुत करने के लिए अनुमति देता है, वहाँ कोई अस्पष्टता नहीं है - इंटरफ़ेस जानता है कि अपने कार्य परिभाषा के शरीर के अंदर किसी भी अर्धविराम पूरे CREATE FUNCTION बयान समाप्त नहीं है। तो DELIMITER के साथ कथन टर्मिनेटर को बदलने की कोई आवश्यकता नहीं है।

+0

जब तक आपको आवश्यकता न हो। उदाहरण के लिए डेटाबेस निर्माण स्क्रिप्ट चलाएं। क्या कच्चे एसक्यूएल को MySQL में पास करने का कोई तरीका है? –

+0

@ ब्रायनहंट, आप गतिशील एसक्यूएल एपीआई के माध्यम से एक मनमानी एसक्यूएल स्क्रिप्ट सबमिट नहीं कर सकते हैं, क्योंकि कई कमांड केवल 'mysql' क्लाइंट द्वारा मान्यता प्राप्त हैं, सर्वर SQL पार्सर नहीं। –

+0

विधेयक, स्पष्टीकरण के लिए धन्यवाद। बी –

4

बिल करविन द्वारा उत्तर में जोड़ने के लिए, निम्नलिखित पायथन कोड नमूना का उपयोग स्ट्रिंग को सही तरीके से निष्पादित करने के लिए किया जा सकता है जहां DELIMITER का उपयोग किया जाता है, जैसे डेटाबेस निर्माण स्क्रिप्ट।

import MySQLdb 

db = MySQLdb.connect(db='service') 
cursor = db.cursor() 

dbString = """DELIMITER // 
CREATE FUNCTION trivial_func (radius float) 
RETURNS FLOAT 

BEGIN 
IF radius > 1 THEN 
    RETURN 0.0; 
ELSE 
    RETURN 1.0; 
END IF; 
END // 

DELIMITER ;""" 

# Find special delimiters 
delimiters = re.compile('DELIMITER *(\S*)',re.I) 
result = delimiters.split(dbString) 

# Insert default delimiter and separate delimiters and sql 
result.insert(0,';') 
delimiter = result[0::2] 
section = result[1::2] 

# Split queries on delimiters and execute 
for i in range(len(delimiter)): 
    queries = section[i].split(delimiter[i]) 
    for query in queries: 
     if not query.strip(): 
      continue 
     cursor.execute(query) 

यह एक समय में एक सीमांकित कथन निष्पादित करेगा, जब आवश्यक हो तो डिलीमीटर को बदल देगा।

+0

यह मेरे लिए चाल है। मुझे अपनी .sql फ़ाइल में% वर्णों से बचने के लिए 'query = query.replace ('% ',' %% ')' जोड़ने की भी आवश्यकता है। – Lundy

0

@AaronS से टिप्पणी के आधार पर। यह स्क्रिप्ट एक SQL फ़ाइल में पढ़ी जाएगी, इसे अलग SQL कमांड में विभाजित करें और जो भी डिलीमीटर इसे पाता है उससे निपटें।

queries = [] 
    delimiter = ';' 
    query = '' 
    with open('import.sql', 'r') as f: 
     for line in f.readlines(): 
      line = line.strip() 
      if line.startswith('DELIMITER'): 
       delimiter = line[10:] 
      else: 
       query += line+'\n' 
       if line.endswith(delimiter): 
        # Get rid of the delimiter, remove any blank lines and add this query to our list 
        queries.append(query.strip().strip(delimiter)) 
        query = '' 

    for query in queries: 
     if not query.strip(): 
      continue 
     cursor.execute(query) 
    cursor.close() 
संबंधित मुद्दे