2011-08-26 19 views
8

मैंने अभी PHP के साथ MySQL का उपयोग करना शुरू कर दिया है और मैं जानना चाहता हूं कि कस्टम फ़ंक्शन बनाना संभव है या नहीं। इस कोड स्निपेट को यह स्पष्ट करना चाहिए कि मैं क्या करने की कोशिश कर रहा हूं।एक कस्टम MySQL फ़ंक्शन बनाना?

// a somewhat complicated formula not suitable to embed into the query 
function Distance($latA, $lonA, $latB, $lonB) 
{ 
    // earth's radius 
    $radius = 3956; 

    $latA = deg2rad($latA); 
    $lonA = deg2rad($lonA); 
    $latB = deg2rad($latB); 
    $lonB = deg2rad($lonB); 

    // calculate deltas 
    $deltaLat = $latB - $latA; 
    $deltaLon = $lonB - $lonA; 

    // calculate Great Circle distance 
    $result = pow(sin($deltaLatitude/2.0), 2) + (cos($latA) * cos($latB) * pow(sin($deltaLon/2.0), 2)); 
    $distance = $radius * 2 * atan2(sqrt($result), sqrt(1 - $result)); 

    return $distance; 
} 

// how can I call Distance() in my query? 
$query = "SELECT lat, lon FROM zipcodes WHERE Distance(lat, lon, 0, 0) < 20"; 
mysql_query($query); 

किसी भी मदद के लिए अग्रिम धन्यवाद!

+1

बस FYI करें, आपको लगता है कि पूरी तरह से एक प्रश्न से लगता है कर सकते हैं। वास्तव में, यदि आप अपने अक्षांश/एलएनजी के आधार पर एक स्थानिक सूचकांक का उपयोग करते हैं और आप पाएंगे कि परिणाम प्रभावशाली हैं। अविश्वसनीय तथ्य। – Layke

+0

मुझे यकीन नहीं है कि आपका क्या मतलब है, क्या आप इस पर विस्तृत जानकारी दे सकते हैं? इसके अलावा "अनुपयुक्त" से मेरा प्रदर्शन प्रदर्शन के संदर्भ में नहीं था (मुझे इसके बारे में कुछ नहीं पता है); मेरा मतलब था कि क्वेरी कितनी दर्दनाक होगी। –

उत्तर

12

आप अपने आवेदन में यह MySQL फ़ंक्शन घोषित करते हैं, और यह डेटाबेस सर्वर में तब तक जारी रहेगा जब तक डेटाबेस सर्वर पुनरारंभ नहीं होता है।

mysql_query("CREATE FUNCTION Distance(LAT_A INT, LON_A INT, LAT_B INT, LON_B INT,) 
RETURNS INT 
READS SQL DATA 
DETERMINISTIC 
BEGIN 
DECLARE radius, deltaLat, deltaLon, result, distance BIGINT; 
SET radius=3956; 
SET deltaLat=LAT_B-LAT_A; 
SET deltaLon=LON_B-LON_A; 
SET result=POW(SIN(deltaLat/2), 2) + (COS(LAT_A) * COS(LAT_B) * POW(SIN(deltaLon/2.0), 2)); 
SET distance=radius * 2 * ATAN2(SQRT(result), SQRT(1 - result)); 
RETURN distance; 
END"); 

यह MySQL के mathematical functions का उपयोग करता है। डेटाबेस में इस प्रसंस्करण को ऑफ़लोड करना तेज़ और कुशल है (डेटा को तार में यात्रा करने की ज़रूरत नहीं है, और आप केवल वही परिणाम लौटाएंगे जिन्हें आप चाहते हैं)।

बार जब आप इस घोषित है, तो आप यह इतना की तरह उपयोग कर सकते हैं:

$query = "SELECT lat, lon FROM zipcodes WHERE Distance(lat, lon, 0, 0) < 20"; 
mysql_query($query); 

लेकिन अगर अपने डेटाबेस को पुनः आरंभ करता है, पहले से घोषित किसी भी कार्य या प्रक्रियाओं खो जाते हैं। आवेदन स्तर पर MySQL त्रुटि 1305 (Function functionName does not exist) को गहन रूप से संभालना संभव है।

अपने डेटाबेस त्रुटि हैंडलर में:

switch (mysql_errno()): 
    case 1305: 
     if (false === $database->_declareStoredProcedureFlag) { 
      if ($c = preg_match_all("/FUNCTION [a-zA-Z0-9]+\." . 
       "([a-zA-Z0-9_]*) does not exist/is", 
       mysql_error(), $matches) 
      ) { 
       $storedFunctionName = $matches[1][0]; 
       $database->_declareStoredProcedureFlag = true; 
       if (true === $database->declareStoredFunction($storedFunctionName)) { 
        $result = mysql_query($query); 
       } 
      } 
     } 
     break; 
    ... 
+0

क्या यह एकमात्र विकल्प है? मैं इस समय इसे PHP तक ही सीमित रखूंगा। मैं एक जवाब चिह्नित करने के लिए कुछ और मिनट इंतजार करूंगा। –

+0

ये मुझे लगता है कि यह नहीं हो रहा है। मैं इसके साथ जाने जा रहा हूँ, +1। चीयर्स दोस्त। –

+1

क्योंकि आप क्वेरी में 'दूरी() 'फ़ंक्शन कॉल में' lat' और 'lon' मानों का उपयोग कर रहे हैं, और ये डेटाबेस से आते हैं, एकमात्र अन्य विकल्प संपूर्ण डेटासेट (उन मानों को शामिल करना) से चुनना है PHP में तालिका, इसे फ़ंक्शन के PHP संस्करण के माध्यम से चलाएं और अनिवार्य रूप से PHP-(जो डेटाबेस को कुशलता से करने के लिए डिज़ाइन किया गया है) चलाएं (जो काफी धीमी है)। उसके बाद डेटाबेस से डेटा को PHP में स्थानांतरित करने के अतिरिक्त ओवरहेड हैं। यह इष्टतम समाधान है, लेकिन स्पष्ट रूप से जटिलता जोड़ता है। – Andy

1

आप निश्चित रूप से ऐसा करने के लिए एक MySQL फ़ंक्शन लिख सकते हैं। मैं अब एक लिखने के लिए समय नहीं है, लेकिन यहाँ आप जहां आरंभ है:।

http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html

+0

ओह, मैंने सोचा था कि आप अपना PHP फ़ंक्शन लेना चाहते हैं और इसे एक MySQL फ़ंक्शन में बनाना चाहते हैं। माफ़ कीजिये! –

+0

एक और जवाब था जो दिखाता है कि "function_ame()" का उपयोग करके फ़ंक्शन को कैसे कॉल करें। सिंटैक्स जो भी आपके काम को PHP में रखना चाहते हैं तो यह भी करने योग्य है। –

0

क्योंकि कार्यों उद्धरण में काम नहीं करते "या 'आप इसे विभाजित करने के लिए एक पूर्ण विराम के साथ है (।)

$query = mysql_query("SELECT lat, lon FROM zipcodes WHERE ".Distance($lat, $lon, 0, 0)." < 20"); 

आशा इस मदद करता है :)

+0

उपरोक्त वर्णित @ thedaian के रूप में, यह 'lat' और' lon' के रूप में काम नहीं करेगा SELECT कथन में चर हैं। –

1

Mysql संग्रहीत दिनचर्या http://dev.mysql.com/doc/refman/5.0/en/stored-routines.html

कार्यों में से कुछ अलग हो सकता है, के लिए उदाहरण के लिए, phs के deg2rad के बराबर mysql mysql के radians() फ़ंक्शन है। मुझे लगता है कि आप एक समकक्ष समारोह बनाने में सक्षम होना चाहिए। इस दृष्टिकोण के साथ, आपको अवगत होना चाहिए कि इन प्रश्नों को हर बार पूरे ज़िपकोड टेबल को टेबलकेन करना होगा।

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