गलत परिणाम भ्रष्टाचार, बग और सुविधाओं के कारण हो सकते हैं जो चुपचाप SQL कथनों को बदल देते हैं।
- भ्रष्ट अनुक्रमणिका। बहुत कम ही कोई अनुक्रमणिका भ्रष्ट होती है और किसी अनुक्रमणिका का डेटा किसी तालिका के डेटा से मेल नहीं खाता है। यह अप्रत्याशित परिणाम देता है जब क्वेरी योजना बदलती है और एक इंडेक्स का उपयोग किया जाता है, लेकिन टेबल एक्सेस का उपयोग करने वाले विभिन्न प्रश्नों के लिए सब कुछ सामान्य दिखता है। कभी-कभी बस पुन:निर्माण करने वाली वस्तुएं इसे ठीक कर सकती हैं। यदि ऐसा नहीं होता है, तो आपको पूरी तरह से प्रतिलिपि प्रस्तुत करने योग्य परीक्षण केस (डेटा सहित) बनाने की आवश्यकता होगी; या तो इसे यहां पोस्ट करें या इसे Oracle सपोर्ट में सबमिट करें। इसे ट्रैक करने में कई घंटे लग सकते हैं।
- बग. बहुत कम ही कोई बग डेटा लौटाते या बदलते समय प्रश्नों के विफल होने का कारण बन सकता है। फिर से, इसका निदान करने के लिए पूरी तरह से प्रतिलिपि प्रस्तुत करने योग्य परीक्षण मामले की आवश्यकता होती है, और इसमें कुछ समय लग सकता है।
- सुविधा जो SQL को बदल देती है SQL कथनों को पारदर्शी रूप से बदलने के कुछ तरीके हैं। वर्चुअल प्राइवेट डेटाबेस (वीपीडी), DBMS_ADVANCED_REWRITE, और SQL ट्रांसलेशन फ्रेमवर्क में देखें।
#3 को रद्द करने के लिए, नीचे दिया गया कोड आपको ऐसा करने के बुरे तरीकों में से एक और इसका पता लगाने का तरीका दिखाता है। सबसे पहले, स्कीमा और कुछ डेटा बनाएं:
CREATE TABLE TRACKING (
A_ID NUMBER,
D_CODE NUMBER,
HOD NUMBER,
ADR_CNT NUMBER,
TTL_CNT NUMBER,
CREATED DATE,
MODIFIED DATE
);
CREATE INDEX HOD_D_CODE_IDX ON TRACKING (HOD, D_CODE);
CREATE UNIQUE INDEX TRACKING_PK ON TRACKING (A_ID, D_CODE, HOD);
CREATE INDEX MOD_DATE_IDX ON TRACKING (MODIFIED);
ALTER TABLE TRACKING ADD CONSTRAINT TRACKING_PK PRIMARY KEY (A_ID, D_CODE, HOD);
insert into tracking values (1,2,3,4,5,sysdate,sysdate);
commit;
सबसे पहले, सब कुछ उम्मीद के मुताबिक काम करता है:
SQL> SELECT * FROM TRACKING;
A_ID D_CODE HOD ADR_CNT TTL_CNT CREATED MODIFIED
---------- ---------- ---------- ---------- ---------- --------- ---------
1 2 3 4 5 17-JUN-16 17-JUN-16
SQL> SELECT COUNT(1) FROM TRACKING;
COUNT(1)
----------
1
फिर कोई ऐसा करता है:
begin
sys.dbms_advanced_rewrite.declare_rewrite_equivalence(
'april_fools',
'SELECT COUNT(1) FROM TRACKING',
'SELECT 0 FROM TRACKING WHERE ROWNUM = 1',
false);
end;
/
अब परिणाम "गलत" हैं:
SQL> ALTER SESSION SET query_rewrite_integrity = trusted;
Session altered.
SQL> SELECT COUNT(1) FROM TRACKING;
COUNT(1)
----------
0
यह शायद व्याख्या योजना को देखकर पता लगाया जा सकता है। नीचे दिए गए उदाहरण में, Predicate 2 - filter(ROWNUM=1)
एक सुराग है कि कुछ गलत है, क्योंकि वह विधेय मूल क्वेरी में नहीं है। कभी-कभी व्याख्या योजना का "नोट्स" खंड आपको बताएगा कि इसे क्यों बदला गया था, लेकिन कभी-कभी यह केवल सुराग देता है।
SQL> explain plan for SELECT COUNT(1) FROM TRACKING;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------
Plan hash value: 1761840423
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 1 (0)| 00:00:01 |
| 1 | VIEW | | 1 | 2 | 1 (0)| 00:00:01 |
|* 2 | COUNT STOPKEY | | | | | |
| 3 | INDEX FULL SCAN| HOD_D_CODE_IDX | 1 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(ROWNUM=1)
15 rows selected.
(एक असंबंधित नोट पर - हमेशा COUNT(*)
. का उपयोग करें COUNT(1)
. के बजाय . COUNT(1)
एक पुराना मिथक है जो कार्गो कल्ट प्रोग्रामिंग जैसा दिखता है।)