क्लाइंट और सर्वर के बीच वास्तव में संचार को रिवर्स इंजीनियर करने के बाद मैं प्रकट कर सकता हूं कि Oracle की DatabaseMetaData.getColumns() विधियां निम्नलिखित SQL क्वेरी भेजती हैं (हालांकि यह ODBC ड्राइवर संस्करणों और सेटिंग्स के साथ बदल सकती है):
declare
in_owner varchar2(128);
in_name varchar2(128);
in_column varchar2(128);
xyzzy SYS_REFCURSOR;
begin
in_owner := :1; // Which resolves to the schema (user) name supplied
in_name := :2; // Which resolves to the table name supplied
in_column := :3; // Which gets set to '%';
open xyzzy for
SELECT NULL AS table_cat,
t.owner AS table_schem,
t.table_name AS table_name,
t.column_name AS column_name,
DECODE( (SELECT a.typecode
FROM ALL_TYPES A
WHERE a.type_name = t.data_type),
'OBJECT', 2002,
'COLLECTION', 2003,
DECODE(substr(t.data_type, 1, 9),
'TIMESTAMP',
DECODE(substr(t.data_type, 10, 1),
'(',
DECODE(substr(t.data_type, 19, 5),
'LOCAL', -102, 'TIME ', -101, 93),
DECODE(substr(t.data_type, 16, 5),
'LOCAL', -102, 'TIME ', -101, 93)),
'INTERVAL ',
DECODE(substr(t.data_type, 10, 3),
'DAY', -104, 'YEA', -103),
DECODE(t.data_type,
'BINARY_DOUBLE', 101,
'BINARY_FLOAT', 100,
'BFILE', -13,
'BLOB', 2004,
'CHAR', 1,
'CLOB', 2005,
'COLLECTION', 2003,
'DATE', 93,
'FLOAT', 6,
'LONG', -1,
'LONG RAW', -4,
'NCHAR', -15,
'NCLOB', 2011,
'NUMBER', 2,
'NVARCHAR', -9,
'NVARCHAR2', -9,
'OBJECT', 2002,
'OPAQUE/XMLTYPE', 2009,
'RAW', -3,
'REF', 2006,
'ROWID', -8,
'SQLXML', 2009,
'UROWI', -8,
'VARCHAR2', 12,
'VARRAY', 2003,
'XMLTYPE', 2009,
1111)))
AS data_type,
t.data_type AS type_name,
DECODE (t.data_precision, null,
DECODE(t.data_type, 'NUMBER',
DECODE(t.data_scale, null, 0 , 38),
DECODE (t.data_type, 'CHAR', t.char_length, 'VARCHAR', t.char_length, 'VARCHAR2', t.char_length, 'NVARCHAR2', t.char_length, 'NCHAR', t.char_length, 'NUMBER', 0, t.data_length) ), t.data_precision)
AS column_size,
0 AS buffer_length,
DECODE (t.data_type, 'NUMBER', DECODE(t.data_precision, null, DECODE(t.data_scale, null, -127 , t.data_scale), t.data_scale), t.data_scale) AS decimal_digits,
10 AS num_prec_radix,
DECODE (t.nullable, 'N', 0, 1) AS nullable,
NULL AS remarks,
t.data_default AS column_def,
0 AS sql_data_type,
0 AS sql_datetime_sub,
t.data_length AS char_octet_length,
t.column_id AS ordinal_position,
DECODE (t.nullable, 'N', 'NO', 'YES') AS is_nullable,
null as SCOPE_CATALOG,
null as SCOPE_SCHEMA,
null as SCOPE_TABLE,
null as SOURCE_DATA_TYPE,
'NO' as IS_AUTOINCREMENT,
t.virtual_column as IS_GENERATEDCOLUMN
FROM all_tab_cols t
WHERE t.owner LIKE in_owner ESCAPE '/'
AND t.table_name LIKE in_name ESCAPE '/'
AND t.column_name LIKE in_column ESCAPE '/'
AND t.user_generated = 'YES'
ORDER BY table_schem, table_name, ordinal_position;
end;
आप इस बात की सराहना कर सकते हैं कि यह थोड़ा धीमा क्यों हो सकता है, विशेष रूप से ALL_TAB_COLS और ALL_TYPES तालिकाओं में से प्रत्येक 1000 के रिकॉर्ड लंबे हो सकते हैं। फिर भी जबकि Oracle पहले आह्वान (मिनट) को निष्पादित करने के लिए संघर्ष करता है, बाद की कॉल लगभग तुरंत परिणाम लौटाती है। यह एक क्लासिक टेबल-जॉइन प्रदर्शन समस्या है, जहां डेटा के एक सबसेट की आवश्यकता होने पर भी इंजन इससे पहले पूरे डेटासेट में शामिल हो जाता है आवश्यक उपसमुच्चय की गणना और वितरण। बाद में डेटा/परिणाम कैशिंग बाद के प्रश्नों के प्रदर्शन को बेहतर बनाने का काम करता है।
बेहतर समाधान यह हो सकता है कि get_ddl() का उपयोग करें और यह थ्रेड .
वैकल्पिक रूप से आप एक डमी क्वेरी निष्पादित करके तालिका पर मेटाडेटा को तेज़ी से क्वेरी करने में सक्षम हो सकते हैं और फिर निम्नानुसार परिणामसेट मेटाडेटा का उपयोग कर सकते हैं (नोट:कॉलम टिप्पणी मेटाडेटा तुरंत उपलब्ध नहीं हो सकता है):
ResultSet rs = connection.CreateStatement.executeQuery("SELECT * from MyTable WHERE 1=0");
ResultSetMetaData md = rs.getMetaData();
for (int ix = 1; ix <= md.getColumnCount(); ix++)
{
int colSize = md.getPrecision(ix);
String nativeType = md.getColumnTypeName(ix);
int jdbcType = md.getColumnType(ix);
// and so on....
}