Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

ओरेकल plsql ट्रिगर के साथ जन्मदिन से आयु की गणना करना और तालिका में आयु सम्मिलित करना

<ब्लॉककोट>

कृपया मदद करें...मुझे वास्तव में इसकी आवश्यकता है...

नहीं, तुम नहीं। मुझे यकीन नहीं है कि आप ध्यान देंगे; और ऐसा कोई कारण नहीं है कि आपको :-) लेकिन:

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

आपको हमेशा चाहिए उस उम्र की गणना करें जब आपको इसकी आवश्यकता हो। यह काफी सरल क्वेरी है और लंबे समय में आपको बहुत दर्द से बचाती है।

select floor(months_between(sysdate,<dob>)/12) from dual

मैंने प्रदर्शित करने के लिए थोड़ा SQL Fiddle सेट किया है

अब, वास्तव में आपके प्रश्न का उत्तर देने के लिए

<ब्लॉककोट>

यह प्रक्रिया ठीक काम करती है लेकिन केवल एक पंक्ति के लिए, लेकिन सभी पंक्तियों के लिए ट्रिगर की आवश्यकता होती है, लेकिन अगर मैं इसे ट्रिगर से कॉल करता हूं तो त्रुटि होती है...

आप त्रुटि का उल्लेख नहीं करते हैं, कृपया इसे भविष्य में करें क्योंकि यह बहुत उपयोगी है, लेकिन मुझे संदेह है कि आप इसे प्राप्त कर रहे हैं

<ब्लॉककोट>

ORA-04091:तालिका string.string उत्परिवर्तित हो रही है, ट्रिगर/फ़ंक्शन इसे नहीं देख सकता है

ऐसा इसलिए है क्योंकि आपकी प्रक्रिया अद्यतन की जा रही तालिका को क्वेरी कर रही है। Oracle डेटा के पठन-संगत दृश्य को बनाए रखने के लिए इसकी अनुमति नहीं देता है। इससे बचने का तरीका यह है कि आप टेबल को क्वेरी न करें, जो आपको करने की जरूरत नहीं है। अपनी कार्यविधि को ऐसे फ़ंक्शन में बदलें जो जन्मतिथि के अनुसार सही परिणाम देता है:

function get_age (pDOB date) return number is
   /* Return the the number of full years between 
      the date given and sysdate.
      */    
begin    
   return floor(months_between(sysdate,pDOB)/12);    
end;

एक बार फिर ध्यान दें कि मैं months_between() . का उपयोग कर रहा हूं कार्य करता है क्योंकि सभी वर्षों में 365 दिन नहीं होते हैं।

फिर अपने ट्रिगर में आप सीधे कॉलम को मान निर्दिष्ट करते हैं।

CREATE OR REPLACE TRIGGER agec before INSERT OR UPDATE ON dates
FOR EACH ROW
BEGIN
   :new.age := get_age(:new.dob);
END;

:new.<column> सिंटैक्स <column> . का संदर्भ है जिसे अपडेट किया जा रहा है। इस मामले में :new.age वास्तविक मूल्य है जिसे तालिका में रखा जाएगा।

इसका मतलब है कि आपकी तालिका स्वचालित रूप से अपडेट हो जाएगी, जो एक डीएमएल ट्रिगर का बिंदु है।

जैसा कि आप देख सकते हैं कि फ़ंक्शन के लिए बहुत कम बिंदु है; आपका ट्रिगर बन सकता है

CREATE OR REPLACE TRIGGER agec before INSERT OR UPDATE ON dates
FOR EACH ROW
BEGIN
   :new.age := floor(months_between(sysdate,:new,DOB)/12);
END; 

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

थोड़ा अलग होने के नाते क्या आप वाकई लोगों को 9,999 साल का होने देना चाहते हैं? या 0.000000000001998 (प्रमाण)? संख्यात्मक सटीकता महत्वपूर्ण . की संख्या पर आधारित होती है अंक; यह (ओरेकल के अनुसार) गैर-शून्य . है केवल संख्याएं। इससे आप आसानी से पकडे जा सकते हैं. डेटाबेस का उद्देश्य संभावित इनपुट मानों को केवल उन तक सीमित करना है जो मान्य हैं। मैं आपके आयु स्तंभ को number(3,0) . के रूप में घोषित करने पर गंभीरता से विचार करूंगा/करूंगी यह सुनिश्चित करने के लिए कि केवल "संभव" मान शामिल हैं।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. क्या पीएल/एसक्यूएल ब्लॉक से एक चयन कथन आउटपुट करना संभव है?

  2. Linux प्लेटफॉर्म के लिए Oracle डाटाबेस 21c

  3. dbms_output.put_line

  4. MySQL COALESCE और NULLIF फ़ंक्शन

  5. oracle10g में एक स्ट्रिंग दिनांक को दिनांक स्वरूप में कैसे बदलें?