जैसा कि SQL भाषा संदर्भ में बताया गया है :
जब प्रकार मेल नहीं खाते हैं, तो टेबल कॉलम पर निहित रूपांतरण किया जाता है। इसे कुछ डमी डेटा के साथ SQL*Plus में ट्रेस करके देखा जा सकता है।
create table t42 (foo varchar2(3 byte));
insert into t42 (foo) values ('10');
insert into t42 (foo) values ('2A');
set autotrace on explain
यह काम करता है:
select * from t42 where foo = '10';
FOO
---
10
Execution Plan
----------------------------------------------------------
Plan hash value: 3843907281
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 3 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T42 | 1 | 3 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("FOO"='10')
Note
-----
- dynamic sampling used for this statement (level=2)
लेकिन यह त्रुटियाँ:
select * from t42 where foo = 10;
ERROR:
ORA-01722: invalid number
Execution Plan
----------------------------------------------------------
Plan hash value: 3843907281
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 3 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T42 | 1 | 3 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_NUMBER("FOO")=10)
फ़िल्टर में अंतर नोट करें; filter("FOO"='10')
बनाम filter(TO_NUMBER("FOO")=10)
. बाद के मामले में, किसी संख्या से तुलना करने पर, एक to_number()
तालिका में प्रत्येक पंक्ति के विरुद्ध प्रदर्शन किया जा रहा है, उस रूपांतरण के परिणाम की तुलना निश्चित मान से की जाती है। इसलिए यदि किसी भी वर्ण मान को परिवर्तित नहीं किया जा सकता है, तो आपको ORA-01722 मिलेगा। लागू किया जा रहा फ़ंक्शन किसी अनुक्रमणिका का उपयोग करना भी बंद कर देगा, यदि कोई उस स्तंभ पर मौजूद है।
जहां यह दिलचस्प हो जाता है यदि आपके पास एक से अधिक फ़िल्टर हैं। Oracle अलग-अलग समय पर अलग-अलग क्रम में उनका मूल्यांकन कर सकता है, इसलिए हो सकता है कि आप हमेशा ORA-01722 न देखें, और यह कभी-कभी पॉप अप होगा। मान लें कि आपके पास where foo = 10 and bar = 'X'
. था . अगर Oracle को लगता है कि वह गैर-X
. को फ़िल्टर कर सकता है मान पहले, यह केवल to_number()
. को लागू करेगा क्या बचा है, और उस छोटे नमूने में foo
. में गैर-संख्यात्मक मान नहीं हो सकते हैं . लेकिन अगर आपके पास and bar = 'Y'
. है , गैर-Y
मानों में गैर-संख्यात्मक, या शामिल हो सकते हैं Oracle foo
. पर फ़िल्टर कर सकता है पहले , इस पर निर्भर करता है कि यह मान कितना चयनात्मक है।
नैतिक यह है कि कभी भी संख्यात्मक जानकारी को वर्ण प्रकार के रूप में संग्रहीत न करें।
मैं नैतिकता का बैकअप लेने के लिए AskTom संदर्भ की तलाश में था, और पहली बार मैंने देखा आसानी से "एक विधेय के क्रम में परिवर्तन" के प्रभाव के साथ-साथ "varchar2's में संख्याओं को संग्रहीत न करें" के प्रभाव को संदर्भित करता है।