1 {*********************************************************}
3 { Zeos Database Objects }
4 { Oracle Database Connectivity Classes }
6 { Originally written by Sergey Seroukhov }
8 {*********************************************************}
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
13 { License Agreement: }
15 { This library is distributed in the hope that it will be }
16 { useful, but WITHOUT ANY WARRANTY; without even the }
17 { implied warranty of MERCHANTABILITY or FITNESS FOR }
18 { A PARTICULAR PURPOSE. See the GNU Lesser General }
19 { Public License for more details. }
21 { The source code of the ZEOS Libraries and packages are }
22 { distributed under the Library GNU General Public }
23 { License (see the file COPYING / COPYING.ZEOS) }
24 { with the following modification: }
25 { As a special exception, the copyright holders of this }
26 { library give you permission to link this library with }
27 { independent modules to produce an executable, }
28 { regardless of the license terms of these independent }
29 { modules, and to copy and distribute the resulting }
30 { executable under terms of your choice, provided that }
31 { you also meet, for each linked independent module, }
32 { the terms and conditions of the license of that module. }
33 { An independent module is a module which is not derived }
34 { from or based on this library. If you modify this }
35 { library, you may extend this exception to your version }
36 { of the library, but you are not obligated to do so. }
37 { If you do not wish to do so, delete this exception }
38 { statement from your version. }
41 { The project web site is located on: }
42 { http://zeos.firmos.at (FORUM) }
43 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
44 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
46 { http://www.sourceforge.net/projects/zeoslib. }
49 { Zeos Development Group. }
50 {********************************************************@}
52 unit ZDbcOracleMetadata;
59 Types, Classes, SysUtils, ZSysUtils, ZDbcIntfs, ZDbcMetadata,
60 ZCompatibility, ZDbcOracleUtils, ZDbcConnection, ZURL,
61 ZDbcCachedResultSet, ZDbcCache;
65 // technobot 2008-06-28 - methods moved as is from TZOracleDatabaseMetadata:
66 {** Implements Oracle Database Information. }
67 TZOracleDatabaseInfo = class(TZAbstractDatabaseInfo)
68 // function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;
69 // const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;
71 // database/driver/server info:
72 function GetDatabaseProductName: string; override;
73 function GetDatabaseProductVersion: string; override;
74 function GetDriverName: string; override;
75 // function GetDriverVersion: string; override; -> Same as parent
76 function GetDriverMajorVersion: Integer; override;
77 function GetDriverMinorVersion: Integer; override;
78 // function GetServerVersion: string; -> Not implemented
80 // capabilities (what it can/cannot do):
81 // function AllProceduresAreCallable: Boolean; override; -> Not implemented
82 // function AllTablesAreSelectable: Boolean; override; -> Not implemented
83 function SupportsMixedCaseIdentifiers: Boolean; override;
84 function SupportsMixedCaseQuotedIdentifiers: Boolean; override;
85 // function SupportsAlterTableWithAddColumn: Boolean; override; -> Not implemented
86 // function SupportsAlterTableWithDropColumn: Boolean; override; -> Not implemented
87 // function SupportsColumnAliasing: Boolean; override; -> Not implemented
88 // function SupportsConvert: Boolean; override; -> Not implemented
89 // function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):
90 // Boolean; override; -> Not implemented
91 // function SupportsTableCorrelationNames: Boolean; override; -> Not implemented
92 // function SupportsDifferentTableCorrelationNames: Boolean; override; -> Not implemented
93 function SupportsExpressionsInOrderBy: Boolean; override;
94 function SupportsOrderByUnrelated: Boolean; override;
95 function SupportsGroupBy: Boolean; override;
96 function SupportsGroupByUnrelated: Boolean; override;
97 function SupportsGroupByBeyondSelect: Boolean; override;
98 // function SupportsLikeEscapeClause: Boolean; override; -> Not implemented
99 // function SupportsMultipleResultSets: Boolean; override; -> Not implemented
100 // function SupportsMultipleTransactions: Boolean; override; -> Not implemented
101 // function SupportsNonNullableColumns: Boolean; override; -> Not implemented
102 // function SupportsMinimumSQLGrammar: Boolean; override; -> Not implemented
103 // function SupportsCoreSQLGrammar: Boolean; override; -> Not implemented
104 // function SupportsExtendedSQLGrammar: Boolean; override; -> Not implemented
105 // function SupportsANSI92EntryLevelSQL: Boolean; override; -> Not implemented
106 // function SupportsANSI92IntermediateSQL: Boolean; override; -> Not implemented
107 // function SupportsANSI92FullSQL: Boolean; override; -> Not implemented
108 function SupportsIntegrityEnhancementFacility: Boolean; override;
109 // function SupportsOuterJoins: Boolean; override; -> Not implemented
110 // function SupportsFullOuterJoins: Boolean; override; -> Not implemented
111 // function SupportsLimitedOuterJoins: Boolean; override; -> Not implemented
112 function SupportsSchemasInDataManipulation: Boolean; override;
113 function SupportsSchemasInProcedureCalls: Boolean; override;
114 function SupportsSchemasInTableDefinitions: Boolean; override;
115 function SupportsSchemasInIndexDefinitions: Boolean; override;
116 function SupportsSchemasInPrivilegeDefinitions: Boolean; override;
117 function SupportsCatalogsInDataManipulation: Boolean; override;
118 function SupportsCatalogsInProcedureCalls: Boolean; override;
119 function SupportsCatalogsInTableDefinitions: Boolean; override;
120 function SupportsCatalogsInIndexDefinitions: Boolean; override;
121 function SupportsCatalogsInPrivilegeDefinitions: Boolean; override;
122 function SupportsPositionedDelete: Boolean; override;
123 function SupportsPositionedUpdate: Boolean; override;
124 function SupportsSelectForUpdate: Boolean; override;
125 function SupportsStoredProcedures: Boolean; override;
126 function SupportsSubqueriesInComparisons: Boolean; override;
127 function SupportsSubqueriesInExists: Boolean; override;
128 function SupportsSubqueriesInIns: Boolean; override;
129 function SupportsSubqueriesInQuantifieds: Boolean; override;
130 function SupportsCorrelatedSubqueries: Boolean; override;
131 function SupportsUnion: Boolean; override;
132 function SupportsUnionAll: Boolean; override;
133 function SupportsOpenCursorsAcrossCommit: Boolean; override;
134 function SupportsOpenCursorsAcrossRollback: Boolean; override;
135 function SupportsOpenStatementsAcrossCommit: Boolean; override;
136 function SupportsOpenStatementsAcrossRollback: Boolean; override;
137 function SupportsTransactions: Boolean; override;
138 function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):
140 function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;
141 function SupportsDataManipulationTransactionsOnly: Boolean; override;
142 function SupportsResultSetType(_Type: TZResultSetType): Boolean; override;
143 function SupportsResultSetConcurrency(_Type: TZResultSetType;
144 Concurrency: TZResultSetConcurrency): Boolean; override;
145 // function SupportsBatchUpdates: Boolean; override; -> Not implemented
146 function SupportsNonEscapedSearchStrings: Boolean; override;
149 function GetMaxBinaryLiteralLength: Integer; override;
150 function GetMaxCharLiteralLength: Integer; override;
151 function GetMaxColumnNameLength: Integer; override;
152 function GetMaxColumnsInGroupBy: Integer; override;
153 function GetMaxColumnsInIndex: Integer; override;
154 function GetMaxColumnsInOrderBy: Integer; override;
155 function GetMaxColumnsInSelect: Integer; override;
156 function GetMaxColumnsInTable: Integer; override;
157 function GetMaxConnections: Integer; override;
158 function GetMaxCursorNameLength: Integer; override;
159 function GetMaxIndexLength: Integer; override;
160 function GetMaxSchemaNameLength: Integer; override;
161 function GetMaxProcedureNameLength: Integer; override;
162 function GetMaxCatalogNameLength: Integer; override;
163 function GetMaxRowSize: Integer; override;
164 function GetMaxStatementLength: Integer; override;
165 function GetMaxStatements: Integer; override;
166 function GetMaxTableNameLength: Integer; override;
167 function GetMaxTablesInSelect: Integer; override;
168 function GetMaxUserNameLength: Integer; override;
170 // policies (how are various data and operations handled):
171 // function IsReadOnly: Boolean; override; -> Not implemented
172 // function IsCatalogAtStart: Boolean; override; -> Not implemented
173 function DoesMaxRowSizeIncludeBlobs: Boolean; override;
174 // function NullsAreSortedHigh: Boolean; override; -> Not implemented
175 // function NullsAreSortedLow: Boolean; override; -> Not implemented
176 // function NullsAreSortedAtStart: Boolean; override; -> Not implemented
177 // function NullsAreSortedAtEnd: Boolean; override; -> Not implemented
178 // function NullPlusNonNullIsNull: Boolean; override; -> Not implemented
179 // function UsesLocalFiles: Boolean; override; -> Not implemented
180 function UsesLocalFilePerTable: Boolean; override;
181 function StoresUpperCaseIdentifiers: Boolean; override;
182 function StoresLowerCaseIdentifiers: Boolean; override;
183 function StoresMixedCaseIdentifiers: Boolean; override;
184 function StoresUpperCaseQuotedIdentifiers: Boolean; override;
185 function StoresLowerCaseQuotedIdentifiers: Boolean; override;
186 function StoresMixedCaseQuotedIdentifiers: Boolean; override;
187 function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;
188 function DataDefinitionCausesTransactionCommit: Boolean; override;
189 function DataDefinitionIgnoredInTransactions: Boolean; override;
191 // interface details (terms, keywords, etc):
192 function GetSchemaTerm: string; override;
193 function GetProcedureTerm: string; override;
194 function GetCatalogTerm: string; override;
195 function GetCatalogSeparator: string; override;
196 function GetSQLKeywords: string; override;
197 function GetNumericFunctions: string; override;
198 function GetStringFunctions: string; override;
199 function GetSystemFunctions: string; override;
200 function GetTimeDateFunctions: string; override;
201 function GetSearchStringEscape: string; override;
202 function GetExtraNameCharacters: string; override;
205 {** Implements Oracle Database Metadata. }
206 TZOracleDatabaseMetadata = class(TZAbstractDatabaseMetadata)
208 function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-28
210 function UncachedGetTables(const Catalog: string; const SchemaPattern: string;
211 const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;
212 function UncachedGetSchemas: IZResultSet; override;
213 // function UncachedGetCatalogs: IZResultSet; override; -> Not implemented
214 function UncachedGetTableTypes: IZResultSet; override;
215 function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;
216 const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;
217 function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;
218 const TableNamePattern: string): IZResultSet; override;
219 function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;
220 const Table: string; const ColumnNamePattern: string): IZResultSet; override;
221 function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;
222 const Table: string): IZResultSet; override;
223 // function UncachedGetImportedKeys(const Catalog: string; const Schema: string;
224 // const Table: string): IZResultSet; override;
225 // function UncachedGetExportedKeys(const Catalog: string; const Schema: string;
226 // const Table: string): IZResultSet; override;
227 // function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;
228 // const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;
229 // const ForeignTable: string): IZResultSet; override;
230 function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;
231 Unique: Boolean; Approximate: Boolean): IZResultSet; override;
232 // function UncachedGetSequences(const Catalog: string; const SchemaPattern: string;
233 // const SequenceNamePattern: string): IZResultSet; virtual; -> Not implemented
234 function UncachedGetProcedures(const Catalog, SchemaPattern,
235 ProcedureNamePattern: string): IZResultSet;override;
236 function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;
237 const ProcedureNamePattern: string; const ColumnNamePattern: string):
238 IZResultSet; override;
239 // function UncachedGetVersionColumns(const Catalog: string; const Schema: string;
240 // const Table: string): IZResultSet; override;
241 // function UncachedGetTypeInfo: IZResultSet; override;
243 destructor Destroy; override;
251 { TZOracleDatabaseInfo }
253 //----------------------------------------------------------------------
254 // First, a variety of minor information about the target database.
257 What's the name of this database product?
258 @return database product name
260 function TZOracleDatabaseInfo.GetDatabaseProductName: string;
266 What's the version of this database product?
267 @return database version
269 function TZOracleDatabaseInfo.GetDatabaseProductVersion: string;
275 What's the name of this JDBC driver?
276 @return JDBC driver name
278 function TZOracleDatabaseInfo.GetDriverName: string;
280 Result := 'Zeos Database Connectivity Driver for Oracle';
284 What's this JDBC driver's major version number?
285 @return JDBC driver major version
287 function TZOracleDatabaseInfo.GetDriverMajorVersion: Integer;
293 What's this JDBC driver's minor version number?
294 @return JDBC driver minor version number
296 function TZOracleDatabaseInfo.GetDriverMinorVersion: Integer;
302 Does the database use a file for each table?
303 @return true if the database uses a local file for each table
305 function TZOracleDatabaseInfo.UsesLocalFilePerTable: Boolean;
311 Does the database treat mixed case unquoted SQL identifiers as
312 case sensitive and as a result store them in mixed case?
313 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return false.
314 @return <code>true</code> if so; <code>false</code> otherwise
316 function TZOracleDatabaseInfo.SupportsMixedCaseIdentifiers: Boolean;
322 Does the database treat mixed case unquoted SQL identifiers as
323 case insensitive and store them in upper case?
324 @return <code>true</code> if so; <code>false</code> otherwise
326 function TZOracleDatabaseInfo.StoresUpperCaseIdentifiers: Boolean;
332 Does the database treat mixed case unquoted SQL identifiers as
333 case insensitive and store them in lower case?
334 @return <code>true</code> if so; <code>false</code> otherwise
336 function TZOracleDatabaseInfo.StoresLowerCaseIdentifiers: Boolean;
342 Does the database treat mixed case unquoted SQL identifiers as
343 case insensitive and store them in mixed case?
344 @return <code>true</code> if so; <code>false</code> otherwise
346 function TZOracleDatabaseInfo.StoresMixedCaseIdentifiers: Boolean;
352 Does the database treat mixed case quoted SQL identifiers as
353 case sensitive and as a result store them in mixed case?
354 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.
355 @return <code>true</code> if so; <code>false</code> otherwise
357 function TZOracleDatabaseInfo.SupportsMixedCaseQuotedIdentifiers: Boolean;
363 Does the database treat mixed case quoted SQL identifiers as
364 case insensitive and store them in upper case?
365 @return <code>true</code> if so; <code>false</code> otherwise
367 function TZOracleDatabaseInfo.StoresUpperCaseQuotedIdentifiers: Boolean;
373 Does the database treat mixed case quoted SQL identifiers as
374 case insensitive and store them in lower case?
375 @return <code>true</code> if so; <code>false</code> otherwise
377 function TZOracleDatabaseInfo.StoresLowerCaseQuotedIdentifiers: Boolean;
383 Does the database treat mixed case quoted SQL identifiers as
384 case insensitive and store them in mixed case?
385 @return <code>true</code> if so; <code>false</code> otherwise
387 function TZOracleDatabaseInfo.StoresMixedCaseQuotedIdentifiers: Boolean;
393 Gets a comma-separated list of all a database's SQL keywords
394 that are NOT also SQL92 keywords.
397 function TZOracleDatabaseInfo.GetSQLKeywords: string;
399 Result := 'ACCESS,ADD,ALTER,AUDIT,CLUSTER,COLUMN,COMMENT,COMPRESS,CONNECT,'
400 + 'DATE,DROP,EXCLUSIVE,FILE,IDENTIFIED,IMMEDIATE,INCREMENT,INDEX,INITIAL,'
401 + 'INTERSECT,LEVEL,LOCK,LONG,MAXEXTENTS,MINUS,MODE,NOAUDIT,NOCOMPRESS,'
402 + 'NOWAIT,NUMBER,OFFLINE,ONLINE,PCTFREE,PRIOR';
406 Gets a comma-separated list of math functions. These are the
407 X/Open CLI math function names used in the JDBC function escape
411 function TZOracleDatabaseInfo.GetNumericFunctions: string;
413 Result := 'ABS,ACOS,ASIN,ATAN,ATAN2,CEILING,COS,EXP,FLOOR,LOG,LOG10,MOD,PI,'
414 + 'POWER,ROUND,SIGN,SIN,SQRT,TAN,TRUNCATE';
418 Gets a comma-separated list of string functions. These are the
419 X/Open CLI string function names used in the JDBC function escape
423 function TZOracleDatabaseInfo.GetStringFunctions: string;
425 Result := 'ASCII,CHAR,CONCAT,LCASE,LENGTH,LTRIM,REPLACE,RTRIM,SOUNDEX,'
430 Gets a comma-separated list of system functions. These are the
431 X/Open CLI system function names used in the JDBC function escape
435 function TZOracleDatabaseInfo.GetSystemFunctions: string;
441 Gets a comma-separated list of time and date functions.
444 function TZOracleDatabaseInfo.GetTimeDateFunctions: string;
446 Result := 'CURDATE,CURTIME,DAYOFMONTH,HOUR,MINUTE,MONTH,NOW,SECOND,YEAR';
450 Gets the string that can be used to escape wildcard characters.
451 This is the string that can be used to escape '_' or '%' in
452 the string pattern style catalog search parameters.
454 <P>The '_' character represents any single character.
455 <P>The '%' character represents any sequence of zero or
458 @return the string used to escape wildcard characters
460 function TZOracleDatabaseInfo.GetSearchStringEscape: string;
466 Gets all the "extra" characters that can be used in unquoted
467 identifier names (those beyond a-z, A-Z, 0-9 and _).
468 @return the string containing the extra characters
470 function TZOracleDatabaseInfo.GetExtraNameCharacters: string;
475 //--------------------------------------------------------------------
476 // Functions describing which features are supported.
479 Are expressions in "ORDER BY" lists supported?
480 @return <code>true</code> if so; <code>false</code> otherwise
482 function TZOracleDatabaseInfo.SupportsExpressionsInOrderBy: Boolean;
488 Can an "ORDER BY" clause use columns not in the SELECT statement?
489 @return <code>true</code> if so; <code>false</code> otherwise
491 function TZOracleDatabaseInfo.SupportsOrderByUnrelated: Boolean;
497 Is some form of "GROUP BY" clause supported?
498 @return <code>true</code> if so; <code>false</code> otherwise
500 function TZOracleDatabaseInfo.SupportsGroupBy: Boolean;
506 Can a "GROUP BY" clause use columns not in the SELECT?
507 @return <code>true</code> if so; <code>false</code> otherwise
509 function TZOracleDatabaseInfo.SupportsGroupByUnrelated: Boolean;
515 Can a "GROUP BY" clause add columns not in the SELECT
516 provided it specifies all the columns in the SELECT?
517 @return <code>true</code> if so; <code>false</code> otherwise
519 function TZOracleDatabaseInfo.SupportsGroupByBeyondSelect: Boolean;
525 Is the SQL Integrity Enhancement Facility supported?
526 @return <code>true</code> if so; <code>false</code> otherwise
528 function TZOracleDatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;
534 What's the database vendor's preferred term for "schema"?
535 @return the vendor term
537 function TZOracleDatabaseInfo.GetSchemaTerm: string;
543 What's the database vendor's preferred term for "procedure"?
544 @return the vendor term
546 function TZOracleDatabaseInfo.GetProcedureTerm: string;
548 Result := 'procedure';
552 What's the database vendor's preferred term for "catalog"?
553 @return the vendor term
555 function TZOracleDatabaseInfo.GetCatalogTerm: string;
561 What's the separator between catalog and table name?
562 @return the separator string
564 function TZOracleDatabaseInfo.GetCatalogSeparator: string;
570 Can a schema name be used in a data manipulation statement?
571 @return <code>true</code> if so; <code>false</code> otherwise
573 function TZOracleDatabaseInfo.SupportsSchemasInDataManipulation: Boolean;
579 Can a schema name be used in a procedure call statement?
580 @return <code>true</code> if so; <code>false</code> otherwise
582 function TZOracleDatabaseInfo.SupportsSchemasInProcedureCalls: Boolean;
588 Can a schema name be used in a table definition statement?
589 @return <code>true</code> if so; <code>false</code> otherwise
591 function TZOracleDatabaseInfo.SupportsSchemasInTableDefinitions: Boolean;
597 Can a schema name be used in an index definition statement?
598 @return <code>true</code> if so; <code>false</code> otherwise
600 function TZOracleDatabaseInfo.SupportsSchemasInIndexDefinitions: Boolean;
606 Can a schema name be used in a privilege definition statement?
607 @return <code>true</code> if so; <code>false</code> otherwise
609 function TZOracleDatabaseInfo.SupportsSchemasInPrivilegeDefinitions: Boolean;
615 Can a catalog name be used in a data manipulation statement?
616 @return <code>true</code> if so; <code>false</code> otherwise
618 function TZOracleDatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;
624 Can a catalog name be used in a procedure call statement?
625 @return <code>true</code> if so; <code>false</code> otherwise
627 function TZOracleDatabaseInfo.SupportsCatalogsInProcedureCalls: Boolean;
633 Can a catalog name be used in a table definition statement?
634 @return <code>true</code> if so; <code>false</code> otherwise
636 function TZOracleDatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;
642 Can a catalog name be used in an index definition statement?
643 @return <code>true</code> if so; <code>false</code> otherwise
645 function TZOracleDatabaseInfo.SupportsCatalogsInIndexDefinitions: Boolean;
651 Can a catalog name be used in a privilege definition statement?
652 @return <code>true</code> if so; <code>false</code> otherwise
654 function TZOracleDatabaseInfo.SupportsCatalogsInPrivilegeDefinitions: Boolean;
660 Is positioned DELETE supported?
661 @return <code>true</code> if so; <code>false</code> otherwise
663 function TZOracleDatabaseInfo.SupportsPositionedDelete: Boolean;
669 Is positioned UPDATE supported?
670 @return <code>true</code> if so; <code>false</code> otherwise
672 function TZOracleDatabaseInfo.SupportsPositionedUpdate: Boolean;
678 Is SELECT for UPDATE supported?
679 @return <code>true</code> if so; <code>false</code> otherwise
681 function TZOracleDatabaseInfo.SupportsSelectForUpdate: Boolean;
687 Are stored procedure calls using the stored procedure escape
689 @return <code>true</code> if so; <code>false</code> otherwise
691 function TZOracleDatabaseInfo.SupportsStoredProcedures: Boolean;
697 Are subqueries in comparison expressions supported?
698 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
699 @return <code>true</code> if so; <code>false</code> otherwise
701 function TZOracleDatabaseInfo.SupportsSubqueriesInComparisons: Boolean;
707 Are subqueries in 'exists' expressions supported?
708 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
709 @return <code>true</code> if so; <code>false</code> otherwise
711 function TZOracleDatabaseInfo.SupportsSubqueriesInExists: Boolean;
717 Are subqueries in 'in' statements supported?
718 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
719 @return <code>true</code> if so; <code>false</code> otherwise
721 function TZOracleDatabaseInfo.SupportsSubqueriesInIns: Boolean;
727 Are subqueries in quantified expressions supported?
728 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
729 @return <code>true</code> if so; <code>false</code> otherwise
731 function TZOracleDatabaseInfo.SupportsSubqueriesInQuantifieds: Boolean;
737 Are correlated subqueries supported?
738 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
739 @return <code>true</code> if so; <code>false</code> otherwise
741 function TZOracleDatabaseInfo.SupportsCorrelatedSubqueries: Boolean;
747 Is SQL UNION supported?
748 @return <code>true</code> if so; <code>false</code> otherwise
750 function TZOracleDatabaseInfo.SupportsUnion: Boolean;
756 Is SQL UNION ALL supported?
757 @return <code>true</code> if so; <code>false</code> otherwise
759 function TZOracleDatabaseInfo.SupportsUnionAll: Boolean;
765 Can cursors remain open across commits?
766 @return <code>true</code> if cursors always remain open;
767 <code>false</code> if they might not remain open
769 function TZOracleDatabaseInfo.SupportsOpenCursorsAcrossCommit: Boolean;
775 Can cursors remain open across rollbacks?
776 @return <code>true</code> if cursors always remain open;
777 <code>false</code> if they might not remain open
779 function TZOracleDatabaseInfo.SupportsOpenCursorsAcrossRollback: Boolean;
785 Can statements remain open across commits?
786 @return <code>true</code> if statements always remain open;
787 <code>false</code> if they might not remain open
789 function TZOracleDatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;
795 Can statements remain open across rollbacks?
796 @return <code>true</code> if statements always remain open;
797 <code>false</code> if they might not remain open
799 function TZOracleDatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;
804 //----------------------------------------------------------------------
805 // The following group of methods exposes various limitations
806 // based on the target database with the current driver.
807 // Unless otherwise specified, a result of zero means there is no
808 // limit, or the limit is not known.
811 How many hex characters can you have in an inline binary literal?
812 @return max binary literal length in hex characters;
813 a result of zero means that there is no limit or the limit is not known
815 function TZOracleDatabaseInfo.GetMaxBinaryLiteralLength: Integer;
821 What's the max length for a character literal?
822 @return max literal length;
823 a result of zero means that there is no limit or the limit is not known
825 function TZOracleDatabaseInfo.GetMaxCharLiteralLength: Integer;
831 What's the limit on column name length?
832 @return max column name length;
833 a result of zero means that there is no limit or the limit is not known
835 function TZOracleDatabaseInfo.GetMaxColumnNameLength: Integer;
841 What's the maximum number of columns in a "GROUP BY" clause?
842 @return max number of columns;
843 a result of zero means that there is no limit or the limit is not known
845 function TZOracleDatabaseInfo.GetMaxColumnsInGroupBy: Integer;
851 What's the maximum number of columns allowed in an index?
852 @return max number of columns;
853 a result of zero means that there is no limit or the limit is not known
855 function TZOracleDatabaseInfo.GetMaxColumnsInIndex: Integer;
861 What's the maximum number of columns in an "ORDER BY" clause?
862 @return max number of columns;
863 a result of zero means that there is no limit or the limit is not known
865 function TZOracleDatabaseInfo.GetMaxColumnsInOrderBy: Integer;
871 What's the maximum number of columns in a "SELECT" list?
872 @return max number of columns;
873 a result of zero means that there is no limit or the limit is not known
875 function TZOracleDatabaseInfo.GetMaxColumnsInSelect: Integer;
881 What's the maximum number of columns in a table?
882 @return max number of columns;
883 a result of zero means that there is no limit or the limit is not known
885 function TZOracleDatabaseInfo.GetMaxColumnsInTable: Integer;
891 How many active connections can we have at a time to this database?
892 @return max number of active connections;
893 a result of zero means that there is no limit or the limit is not known
895 function TZOracleDatabaseInfo.GetMaxConnections: Integer;
901 What's the maximum cursor name length?
902 @return max cursor name length in bytes;
903 a result of zero means that there is no limit or the limit is not known
905 function TZOracleDatabaseInfo.GetMaxCursorNameLength: Integer;
911 Retrieves the maximum number of bytes for an index, including all
912 of the parts of the index.
913 @return max index length in bytes, which includes the composite of all
914 the constituent parts of the index;
915 a result of zero means that there is no limit or the limit is not known
917 function TZOracleDatabaseInfo.GetMaxIndexLength: Integer;
923 What's the maximum length allowed for a schema name?
924 @return max name length in bytes;
925 a result of zero means that there is no limit or the limit is not known
927 function TZOracleDatabaseInfo.GetMaxSchemaNameLength: Integer;
933 What's the maximum length of a procedure name?
934 @return max name length in bytes;
935 a result of zero means that there is no limit or the limit is not known
937 function TZOracleDatabaseInfo.GetMaxProcedureNameLength: Integer;
943 What's the maximum length of a catalog name?
944 @return max name length in bytes;
945 a result of zero means that there is no limit or the limit is not known
947 function TZOracleDatabaseInfo.GetMaxCatalogNameLength: Integer;
953 What's the maximum length of a single row?
954 @return max row size in bytes;
955 a result of zero means that there is no limit or the limit is not known
957 function TZOracleDatabaseInfo.GetMaxRowSize: Integer;
963 Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY
965 @return <code>true</code> if so; <code>false</code> otherwise
967 function TZOracleDatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;
973 What's the maximum length of an SQL statement?
974 @return max length in bytes;
975 a result of zero means that there is no limit or the limit is not known
977 function TZOracleDatabaseInfo.GetMaxStatementLength: Integer;
983 How many active statements can we have open at one time to this
985 @return the maximum number of statements that can be open at one time;
986 a result of zero means that there is no limit or the limit is not known
988 function TZOracleDatabaseInfo.GetMaxStatements: Integer;
994 What's the maximum length of a table name?
995 @return max name length in bytes;
996 a result of zero means that there is no limit or the limit is not known
998 function TZOracleDatabaseInfo.GetMaxTableNameLength: Integer;
1004 What's the maximum number of tables in a SELECT statement?
1005 @return the maximum number of tables allowed in a SELECT statement;
1006 a result of zero means that there is no limit or the limit is not known
1008 function TZOracleDatabaseInfo.GetMaxTablesInSelect: Integer;
1014 What's the maximum length of a user name?
1015 @return max user name length in bytes;
1016 a result of zero means that there is no limit or the limit is not known
1018 function TZOracleDatabaseInfo.GetMaxUserNameLength: Integer;
1023 //----------------------------------------------------------------------
1026 What's the database's default transaction isolation level? The
1027 values are defined in <code>java.sql.Connection</code>.
1028 @return the default isolation level
1031 function TZOracleDatabaseInfo.GetDefaultTransactionIsolation:
1032 TZTransactIsolationLevel;
1034 Result := tiReadCommitted;
1038 Are transactions supported? If not, invoking the method
1039 <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.
1040 @return <code>true</code> if transactions are supported; <code>false</code> otherwise
1042 function TZOracleDatabaseInfo.SupportsTransactions: Boolean;
1048 Does this database support the given transaction isolation level?
1049 @param level the values are defined in <code>java.sql.Connection</code>
1050 @return <code>true</code> if so; <code>false</code> otherwise
1053 function TZOracleDatabaseInfo.SupportsTransactionIsolationLevel(
1054 Level: TZTransactIsolationLevel): Boolean;
1060 Are both data definition and data manipulation statements
1061 within a transaction supported?
1062 @return <code>true</code> if so; <code>false</code> otherwise
1064 function TZOracleDatabaseInfo.
1065 SupportsDataDefinitionAndDataManipulationTransactions: Boolean;
1071 Are only data manipulation statements within a transaction
1073 @return <code>true</code> if so; <code>false</code> otherwise
1075 function TZOracleDatabaseInfo.
1076 SupportsDataManipulationTransactionsOnly: Boolean;
1082 Does a data definition statement within a transaction force the
1083 transaction to commit?
1084 @return <code>true</code> if so; <code>false</code> otherwise
1086 function TZOracleDatabaseInfo.DataDefinitionCausesTransactionCommit: Boolean;
1092 Is a data definition statement within a transaction ignored?
1093 @return <code>true</code> if so; <code>false</code> otherwise
1095 function TZOracleDatabaseInfo.DataDefinitionIgnoredInTransactions: Boolean;
1101 Does the database support the given result set type?
1102 @param type defined in <code>java.sql.ResultSet</code>
1103 @return <code>true</code> if so; <code>false</code> otherwise
1105 function TZOracleDatabaseInfo.SupportsResultSetType(
1106 _Type: TZResultSetType): Boolean;
1108 Result := _Type = rtForwardOnly;
1112 Does the database support the concurrency type in combination
1113 with the given result set type?
1115 @param type defined in <code>java.sql.ResultSet</code>
1116 @param concurrency type defined in <code>java.sql.ResultSet</code>
1117 @return <code>true</code> if so; <code>false</code> otherwise
1119 function TZOracleDatabaseInfo.SupportsResultSetConcurrency(
1120 _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;
1122 Result := (_Type = rtForwardOnly) and (Concurrency = rcReadOnly);
1126 Does the Database or Actual Version understand non escaped search strings?
1127 @return <code>true</code> if the DataBase does understand non escaped
1130 function TZOracleDatabaseInfo.SupportsNonEscapedSearchStrings: Boolean;
1132 Result := MetaData.GetConnection.GetClientVersion > 10000000;
1135 { TZOracleDatabaseMetadata }
1138 Destroys this object and cleanups the memory.
1140 destructor TZOracleDatabaseMetadata.Destroy;
1146 Constructs a database information object and returns the interface to it. Used
1147 internally by the constructor.
1148 @return the database information object interface
1150 function TZOracleDatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;
1152 Result := TZOracleDatabaseInfo.Create(Self);
1156 Gets a description of tables available in a catalog.
1158 <P>Only table descriptions matching the catalog, schema, table
1159 name and type criteria are returned. They are ordered by
1160 TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
1162 <P>Each table description has the following columns:
1164 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1165 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1166 <LI><B>TABLE_NAME</B> String => table name
1167 <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
1168 "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
1169 "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1170 <LI><B>REMARKS</B> String => explanatory comment on the table
1173 <P><B>Note:</B> Some databases may not return information for
1176 @param catalog a catalog name; "" retrieves those without a
1177 catalog; null means drop catalog name from the selection criteria
1178 @param schemaPattern a schema name pattern; "" retrieves those
1180 @param tableNamePattern a table name pattern
1181 @param types a list of table types to include; null returns all types
1182 @return <code>ResultSet</code> - each row is a table description
1183 @see #getSearchStringEscape
1185 function TZOracleDatabaseMetadata.UncachedGetTables(const Catalog: string;
1186 const SchemaPattern: string; const TableNamePattern: string;
1187 const Types: TStringDynArray): IZResultSet;
1189 NameCondition, OwnerCondition, PartSQL, SQL: string;
1191 function IncludedType(const TypeName: string): Boolean;
1195 for I := Low(Types) to High(Types) do
1196 Result := Result or (UpperCase(Types[I]) = TypeName);
1197 Result := Result or (Length(Types) = 0);
1200 function CreateWhere: String;
1203 If OwnerCondition <> '' then
1204 Result := OwnerCondition;
1205 If NameCondition <> '' then
1206 If Result <> '' then
1207 Result := Result + ' AND ' + NameCondition
1209 Result := NameCondition;
1210 If Result <> '' then
1211 Result := ' Where ' + Result;
1215 OwnerCondition := ConstructNameCondition(SchemaPattern,'OWNER');
1217 if IncludedType('TABLE') then
1219 NameCondition := ConstructNameCondition(TableNamePattern,'TABLE_NAME');
1220 SQL := 'SELECT NULL AS TABLE_CAT, OWNER AS TABLE_SCHEM, TABLE_NAME,'
1221 + ' ''TABLE'' AS TABLE_TYPE, NULL AS REMARKS FROM SYS.ALL_TABLES'
1226 if IncludedType('SYNONYM') then
1228 NameCondition := ConstructNameCondition(TableNamePattern,'SYNONYM_NAME');
1229 PartSQL := 'SELECT NULL AS TABLE_CAT, OWNER AS TABLE_SCHEM,'
1230 + ' SYNONYM_NAME AS TABLE_NAME, ''SYNONYM'' AS TABLE_TYPE,'
1231 + ' NULL AS REMARKS FROM SYS.ALL_SYNONYMS'
1234 SQL := SQL + ' UNION ';
1235 SQL := SQL + PartSQL;
1238 if IncludedType('VIEW') then
1240 NameCondition := ConstructNameCondition(TableNamePattern,'VIEW_NAME');
1241 PartSQL := 'SELECT NULL AS TABLE_CAT, OWNER AS TABLE_SCHEM,'
1242 + ' VIEW_NAME AS TABLE_NAME, ''VIEW'' AS TABLE_TYPE,'
1243 + ' NULL AS REMARKS FROM SYS.ALL_VIEWS'
1246 SQL := SQL + ' UNION ';
1247 SQL := SQL + PartSQL;
1250 if IncludedType('SEQUENCE') then
1252 OwnerCondition := ConstructNameCondition(SchemaPattern,'SEQUENCE_OWNER');
1253 NameCondition := ConstructNameCondition(TableNamePattern,'SEQUENCE_NAME');
1254 PartSQL := 'SELECT NULL AS TABLE_CAT, SEQUENCE_OWNER AS TABLE_SCHEM,'
1255 + ' SEQUENCE_NAME AS TABLE_NAME, ''SEQUENCE'' AS TABLE_TYPE,'
1256 + ' NULL AS REMARKS FROM SYS.ALL_SEQUENCES'
1259 SQL := SQL + ' UNION ';
1260 SQL := SQL + PartSQL;
1263 Result := CopyToVirtualResultSet(
1264 GetConnection.CreateStatement.ExecuteQuery(SQL),
1265 ConstructVirtualResultSet(TableColumnsDynArray));
1269 function TZOracleDatabaseMetadata.UncachedGetProcedureColumns(const Catalog,
1270 SchemaPattern, ProcedureNamePattern, ColumnNamePattern: string): IZResultSet;
1272 ColumnIndexes : Array[1..9] of integer;
1274 IZStmt: IZStatement;
1275 TempSet: IZResultSet;
1276 Names, Procs: TStrings;
1277 PackageName, ProcName, TempProcedureNamePattern, TmpSchemaPattern: String;
1279 function GetNextName(const AName: String; NameEmpty: Boolean = False): String;
1284 if ( PackageName = '' ) or ( not ( PackageName = ProcedureNamePattern ) ) then
1287 NewName := ProcName+'.'+AName;
1288 if (Names.IndexOf(NewName) = -1) and not NameEmpty then
1294 for N := 1 to MaxInt do
1295 if Names.IndexOf(NewName+IntToStr(N)) = -1 then
1297 Result := NewName+IntToStr(N);
1303 procedure InsertProcedureColumnValues(Source: IZResultSet; IsResultParam: Boolean = False);
1305 TypeName, SubTypeName: string;
1307 TypeName := Source.GetString(ColumnIndexes[4]);
1308 SubTypeName := Source.GetString(ColumnIndexes[5]);
1309 PackageName := Source.GetString(ColumnIndexes[8]);
1310 ProcName := Source.GetString(ColumnIndexes[9]);
1312 Result.MoveToInsertRow;
1313 Result.UpdateNull(1); //PROCEDURE_CAT
1314 Result.UpdateNull(2); //PROCEDURE_SCHEM
1315 Result.UpdateString(3, Source.GetString(ColumnIndexes[1])); //TABLE_NAME
1316 if IsResultParam then
1317 Result.UpdateInt(5, Ord(pctReturn))
1319 if Source.GetString(ColumnIndexes[3]) = 'IN' then
1320 Result.UpdateInt(5, Ord(pctIn))
1322 if Source.GetString(ColumnIndexes[3]) = 'OUT' then
1323 Result.UpdateInt(5, Ord(pctOut))
1325 if ( Source.GetString(ColumnIndexes[3]) = 'IN/OUT') then
1326 Result.UpdateInt(5, Ord(pctInOut))
1328 Result.UpdateInt(5, Ord(pctUnknown));
1330 ColName := Source.GetString(ColumnIndexes[2]);
1331 if IsResultParam then
1332 Result.UpdateString(4, GetNextName('ReturnValue', False)) //COLUMN_NAME
1334 Result.UpdateString(4, GetNextName(ColName, Length(ColName) = 0)); //COLUMN_NAME
1336 Result.UpdateInt(6, Ord(ConvertOracleTypeToSQLType(TypeName,
1337 Source.GetInt(ColumnIndexes[6]),Source.GetInt(ColumnIndexes[7]),
1338 ConSettings.CPType))); //DATA_TYPE
1339 Result.UpdateString(7,TypeName); //TYPE_NAME
1340 Result.UpdateInt(10, Source.GetInt(ColumnIndexes[6])); //PRECISION
1341 Result.UpdateNull(9); //BUFFER_LENGTH
1342 Result.UpdateInt(10, Source.GetInt(ColumnIndexes[7]));
1343 Result.UpdateInt(11, 10);
1344 //Result.UpdateInt(12, GetInt(ColumnIndexes[8]));
1345 Result.UpdateNull(12);
1346 Result.UpdateString(12, Source.GetString(ColumnIndexes[6]));
1350 function GetColumnSQL(PosChar: String; Package: String = ''): String;
1352 OwnerCondition, PackageNameCondition, PackageAsProcCondition, PackageProcNameCondition: string;
1354 procedure SplitPackageAndProc(Value: String);
1359 ProcName := 'Value';
1360 iPos := Pos('.', Value);
1363 PackageNameCondition := ConstructNameCondition(Copy(Value, 1, iPos-1),'package_name');
1364 PackageProcNameCondition := ConstructNameCondition(Copy(Value, iPos+1,Length(Value)-iPos),'object_name');
1365 PackageAsProcCondition := ConstructNameCondition(Copy(Value, iPos+1,Length(Value)-iPos),'package_name');
1366 PackageName := '= '+#39+IC.ExtractQuote(Copy(Value, 1, iPos-1))+#39;
1367 ProcName := IC.ExtractQuote(Copy(Value, iPos+1,Length(Value)-iPos));
1371 PackageNameCondition := 'package_name IS NULL';
1372 PackageProcNameCondition := ConstructNameCondition(Value,'object_name');
1373 PackageAsProcCondition := ConstructNameCondition(Value,'package_name');
1374 PackageName := 'IS NULL';
1375 ProcName := IC.ExtractQuote(Value);
1379 OwnerCondition := ConstructNameCondition(TmpSchemaPattern,'OWNER');
1380 SplitPackageAndProc(TempProcedureNamePattern);
1381 Result := 'select * from all_arguments where ('+PackageNameCondition+
1382 ' AND '+PackageProcNameCondition+
1383 ' OR '+ PackageAsProcCondition+')'+
1384 'AND POSITION '+PosChar+' 0';
1385 If OwnerCondition <> '' then
1386 Result := Result + ' AND ' + OwnerCondition;
1387 Result := Result + ' ORDER BY POSITION';
1390 procedure AddColumns(WasNext: Boolean; WasFunc: Boolean);
1392 if WasNext then InsertProcedureColumnValues(TempSet, WasFunc);
1393 while TempSet.Next do
1394 InsertProcedureColumnValues(TempSet, WasFunc);
1399 TempSet := IZStmt.ExecuteQuery(GetColumnSQL('=')); //ReturnValue has allways Position = 0
1403 InsertProcedureColumnValues(TempSet, True);
1409 procedure GetMoreProcedures;
1412 PackageNameCondition: String;
1414 PackageNameCondition := ConstructNameCondition(ProcedureNamePattern,'package_name');
1415 If PackageNameCondition <> '' then
1416 PackageNameCondition := ' WHERE ' + PackageNameCondition;
1418 TempSet := IZStmt.ExecuteQuery('select object_name from user_arguments '
1419 + PackageNameCondition + ' GROUP BY object_name order by object_name');
1420 while TempSet.Next do
1421 Procs.Add(TempSet.GetString(1));
1423 for i := 0 to Procs.Count -1 do
1425 TempProcedureNamePattern := ProcedureNamePattern+'.'+IC.Quote(Procs[i]);
1426 TempSet := IZStmt.ExecuteQuery(GetColumnSQL('>')); //ParameterValues have allways Position > 0
1427 AddColumns(False, False);
1431 function CheckSchema: Boolean;
1433 if TmpSchemaPattern = '' then
1436 with GetConnection.CreateStatement.ExecuteQuery('SELECT COUNT(*) FROM ALL_USERS WHERE '+ConstructNameCondition(TmpSchemaPattern,'username')) do
1439 Result := GetInt(1) > 0;
1444 Result:=inherited UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);
1446 {improve SplitQualifiedObjectName: Oracle does'nt support catalogs}
1447 if Catalog = '' then
1448 TmpSchemaPattern := SchemaPattern
1450 TmpSchemaPattern := Catalog;
1452 if ( TmpSchemaPattern = '' ) then
1453 TempProcedureNamePattern := ProcedureNamePattern //just a procedurename or package or both
1456 TempProcedureNamePattern := ProcedureNamePattern //Schema exists not a package
1459 TempProcedureNamePattern := TmpSchemaPattern+'.'+ProcedureNamePattern; //no Schema so it's a PackageName
1460 TmpSchemaPattern := '';
1462 if TempProcedureNamePattern <> '' then
1464 Names := TStringList.Create;
1465 Procs := TStringList.Create;
1467 IZStmt := GetConnection.CreateStatement;
1468 TempSet := IZStmt.ExecuteQuery(GetColumnSQL('>')); //ParameterValues have allways Position > 0
1472 ColumnIndexes[1] := FindColumn('object_name');
1473 ColumnIndexes[2] := FindColumn('argument_name');
1474 ColumnIndexes[3] := FindColumn('IN_OUT'); //'RDB$PARAMETER_TYPE');
1475 ColumnIndexes[4] := FindColumn('DATA_TYPE');//'RDB$FIELD_TYPE');
1476 ColumnIndexes[5] := FindColumn('TYPE_SUBNAME');//RDB$FIELD_SUB_TYPE');
1477 ColumnIndexes[6] := FindColumn('DATA_PRECISION');//RDB$FIELD_PRECISION');
1478 ColumnIndexes[7] := FindColumn('DATA_SCALE');//RDB$FIELD_SCALE');
1479 ColumnIndexes[8] := FindColumn('package_name');
1480 ColumnIndexes[9] := FindColumn('object_name');
1482 if ( PackageName <> 'IS NULL' ) and ( ProcName <> '' ) then
1483 AddColumns(False, False)
1485 if TempSet.Next then
1486 if ( TempSet.GetString(ColumnIndexes[8]) = ProcName ) then
1487 {Package without proc found}
1490 AddColumns(True, False)
1494 TempSet := IZStmt.ExecuteQuery(GetColumnSQL('=')); //ParameterValues have allways Position > 0
1495 if TempSet.Next then
1496 if ( TempSet.GetString(ColumnIndexes[8]) = ProcName ) then
1497 {Package without proc found}
1500 AddColumns(True, True)
1509 function TZOracleDatabaseMetadata.UncachedGetProcedures(const Catalog: string;
1510 const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;
1513 LProcedureNamePattern, LSchemaNamePattern: string;
1516 Result:=inherited UncachedGetProcedures(Catalog, SchemaPattern, ProcedureNamePattern);
1518 LProcedureNamePattern := ConstructNameCondition(ProcedureNamePattern,'decode(procedure_name,null,object_name,object_name||''.''||procedure_name)');
1519 LSchemaNamePattern := ConstructNameCondition(SchemaPattern,'owner');
1520 SQL := 'select NULL AS PROCEDURE_CAT, OWNER AS PROCEDURE_SCHEM, '+
1521 'OBJECT_NAME, PROCEDURE_NAME AS PROCEDURE_NAME, '+
1522 'OVERLOAD AS PROCEDURE_OVERLOAD, OBJECT_TYPE AS PROCEDURE_TYPE FROM '+
1523 'ALL_PROCEDURES WHERE 1=1';
1524 if LProcedureNamePattern <> '' then
1525 SQL := SQL + ' AND ' + LProcedureNamePattern;
1526 if LSchemaNamePattern <> '' then
1527 SQL := SQL + ' AND ' + LSchemaNamePattern;
1528 SQL := SQL + ' ORDER BY decode(owner,user,0,1),owner,object_name,procedure_name,overload';
1530 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
1534 sName := IC.Quote(GetString(3));
1535 if GetString(4) <> '' then
1536 sName := sName+'.'+IC.Quote(GetString(4));
1537 Result.MoveToInsertRow;
1538 Result.UpdateNull(1);
1539 Result.UpdateString(2, GetString(2));
1540 Result.UpdateString(3, sName); //PROCEDURE_NAME
1541 Result.UpdateString(4, GetString(5)); //PROCEDURE_OVERLOAD
1542 Result.UpdateNull(5);
1543 Result.UpdateNull(6);
1544 Result.UpdateNull(7);
1545 if GetString(6) = 'FUNCTION' then
1546 Result.UpdateInt(8, Ord(prtReturnsResult))
1547 else if GetString(6) = 'PROCDEURE' then
1548 Result.UpdateInt(8, Ord(prtNoResult))
1550 Result.UpdateInt(8, Ord(prtUnknown)); //Package
1559 Gets the schema names available in this database. The results
1560 are ordered by schema name.
1562 <P>The schema column is:
1564 <LI><B>TABLE_SCHEM</B> String => schema name
1567 @return <code>ResultSet</code> - each row has a single String column that is a
1570 function TZOracleDatabaseMetadata.UncachedGetSchemas: IZResultSet;
1572 Result := CopyToVirtualResultSet(
1573 GetConnection.CreateStatement.ExecuteQuery(
1574 'SELECT USERNAME AS TABLE_SCHEM FROM SYS.ALL_USERS'),
1575 ConstructVirtualResultSet(SchemaColumnsDynArray));
1579 Gets the table types available in this database. The results
1580 are ordered by table type.
1582 <P>The table type is:
1584 <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
1585 "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
1586 "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1589 @return <code>ResultSet</code> - each row has a single String column that is a
1592 function TZOracleDatabaseMetadata.UncachedGetTableTypes: IZResultSet;
1595 Types: array [1..TableTypeCount] of String = (
1596 'TABLE', 'SYNONYM', 'VIEW', 'SEQUENCE'
1601 Result:=inherited UncachedGetTableTypes;
1603 for I := 1 to TableTypeCount do
1605 Result.MoveToInsertRow;
1606 Result.UpdateString(1, Types[I]);
1612 Gets a description of table columns available in
1613 the specified catalog.
1615 <P>Only column descriptions matching the catalog, schema, table
1616 and column name criteria are returned. They are ordered by
1617 TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
1619 <P>Each column description has the following columns:
1621 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1622 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1623 <LI><B>TABLE_NAME</B> String => table name
1624 <LI><B>COLUMN_NAME</B> String => column name
1625 <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
1626 <LI><B>TYPE_NAME</B> String => Data source dependent type name,
1627 for a UDT the type name is fully qualified
1628 <LI><B>COLUMN_SIZE</B> int => column size. For char or date
1629 types this is the maximum number of characters, for numeric or
1630 decimal types this is precision.
1631 <LI><B>BUFFER_LENGTH</B> is not used.
1632 <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
1633 <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
1634 <LI><B>NULLABLE</B> int => is NULL allowed?
1636 <LI> columnNoNulls - might not allow NULL values
1637 <LI> columnNullable - definitely allows NULL values
1638 <LI> columnNullableUnknown - nullability unknown
1640 <LI><B>REMARKS</B> String => comment describing column (may be null)
1641 <LI><B>COLUMN_DEF</B> String => default value (may be null)
1642 <LI><B>SQL_DATA_TYPE</B> int => unused
1643 <LI><B>SQL_DATETIME_SUB</B> int => unused
1644 <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
1645 maximum number of bytes in the column
1646 <LI><B>ORDINAL_POSITION</B> int => index of column in table
1648 <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
1649 does not allow NULL values; "YES" means the column might
1650 allow NULL values. An empty string means nobody knows.
1653 @param catalog a catalog name; "" retrieves those without a
1654 catalog; null means drop catalog name from the selection criteria
1655 @param schemaPattern a schema name pattern; "" retrieves those
1657 @param tableNamePattern a table name pattern
1658 @param columnNamePattern a column name pattern
1659 @return <code>ResultSet</code> - each row is a column description
1660 @see #getSearchStringEscape
1662 function TZOracleDatabaseMetadata.UncachedGetColumns(const Catalog: string;
1663 const SchemaPattern: string; const TableNamePattern: string;
1664 const ColumnNamePattern: string): IZResultSet;
1668 OwnerCondition,TableCondition,ColumnCondition: String;
1670 function CreateWhere: String;
1673 If OwnerCondition <> '' then
1674 Result := OwnerCondition;
1675 If TableCondition <> '' then
1676 If Result <> '' then
1677 Result := Result + ' AND ' + TableCondition
1679 Result := TableCondition;
1680 If ColumnCondition <> '' then
1681 If Result <> '' then
1682 Result := Result + ' AND ' + ColumnCondition
1684 Result := ColumnCondition;
1685 If Result <> '' then
1686 Result := ' Where ' + Result;
1690 OwnerCondition := ConstructNameCondition(SchemaPattern,'OWNER');
1691 TableCondition := ConstructNameCondition(TableNamePattern,'TABLE_NAME');
1692 ColumnCondition := ConstructNameCondition(ColumnNamePattern,'COLUMN_NAME');
1693 Result:=inherited UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);
1695 SQL := 'SELECT NULL, OWNER, TABLE_NAME, COLUMN_NAME, NULL, DATA_TYPE,'
1696 + ' DATA_LENGTH, NULL, DATA_PRECISION, DATA_SCALE, NULLABLE, NULL,'
1697 + ' DATA_DEFAULT, NULL, NULL, NULL, COLUMN_ID, NULLABLE'
1698 + ' FROM SYS.ALL_TAB_COLUMNS'
1701 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
1705 Result.MoveToInsertRow;
1706 Result.UpdateNull(1);
1707 Result.UpdateString(2, GetString(2));
1708 Result.UpdateString(3, GetString(3));
1709 Result.UpdateString(4, GetString(4));
1710 SQLType := ConvertOracleTypeToSQLType(GetString(6), GetInt(9),
1711 GetInt(10), ConSettings.CPType);
1712 Result.UpdateInt(5, Ord(SQLType));
1713 Result.UpdateString(6, GetString(6));
1714 Result.UpdateInt(7, GetFieldSize(SQLType, ConSettings, GetInt(7), ConSettings.ClientCodePage.CharWidth)); //FIELD_SIZE
1715 Result.UpdateNull(8);
1716 Result.UpdateInt(9, GetInt(9));
1717 Result.UpdateInt(10, GetInt(10));
1719 if UpperCase(GetString(11)) = 'N' then
1721 Result.UpdateInt(11, Ord(ntNoNulls));
1722 Result.UpdateString(18, 'NO');
1726 Result.UpdateInt(11, Ord(ntNullable));
1727 Result.UpdateString(18, 'YES');
1730 Result.UpdateNull(12);
1731 Result.UpdateString(13, GetString(13));
1732 Result.UpdateNull(14);
1733 Result.UpdateNull(15);
1734 Result.UpdateNull(16);
1735 Result.UpdateInt(17, GetInt(17));
1737 Result.UpdateNull(19); //AUTO_INCREMENT
1738 Result.UpdateBoolean(20, //CASE_SENSITIVE
1739 IC.IsCaseSensitive(GetString(4)));
1740 Result.UpdateBoolean(21, True); //SEARCHABLE
1741 Result.UpdateBoolean(22, not (GetString(6) = 'BFILE')); //WRITABLE
1742 Result.UpdateBoolean(23, True); //DEFINITELYWRITABLE
1743 Result.UpdateBoolean(24, (GetString(6) = 'BFILE')); //READONLY
1752 Gets a description of the access rights for a table's columns.
1754 <P>Only privileges matching the column name criteria are
1755 returned. They are ordered by COLUMN_NAME and PRIVILEGE.
1757 <P>Each privilige description has the following columns:
1759 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1760 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1761 <LI><B>TABLE_NAME</B> String => table name
1762 <LI><B>COLUMN_NAME</B> String => column name
1763 <LI><B>GRANTOR</B> => grantor of access (may be null)
1764 <LI><B>GRANTEE</B> String => grantee of access
1765 <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1766 INSERT, UPDATE, REFRENCES, ...)
1767 <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1768 to grant to others; "NO" if not; null if unknown
1771 @param catalog a catalog name; "" retrieves those without a
1772 catalog; null means drop catalog name from the selection criteria
1773 @param schema a schema name; "" retrieves those without a schema
1774 @param table a table name
1775 @param columnNamePattern a column name pattern
1776 @return <code>ResultSet</code> - each row is a column privilege description
1777 @see #getSearchStringEscape
1779 function TZOracleDatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;
1780 const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;
1783 OwnerCondition,TableCondition,ColumnCondition: String;
1785 function CreateWhere: String;
1788 If OwnerCondition <> '' then
1789 Result := OwnerCondition;
1790 If TableCondition <> '' then
1791 If Result <> '' then
1792 Result := Result + ' AND ' + TableCondition
1794 Result := TableCondition;
1795 If ColumnCondition <> '' then
1796 If Result <> '' then
1797 Result := Result + ' AND ' + ColumnCondition
1799 Result := ColumnCondition;
1800 If Result <> '' then
1801 Result := ' Where ' + Result;
1805 OwnerCondition := ConstructNameCondition(Schema,'TABLE_SCHEMA');
1806 TableCondition := ConstructNameCondition(Table,'TABLE_NAME');
1807 ColumnCondition := ConstructNameCondition(ColumnNamePattern,'COLUMN_NAME');
1808 SQL := 'SELECT NULL AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME,'
1809 + ' COLUMN_NAME, GRANTOR, GRANTEE, PRIVILEGE, GRANTABLE AS IS_GRANTABLE'
1810 + ' FROM SYS.ALL_COL_PRIVS'
1813 Result := CopyToVirtualResultSet(
1814 GetConnection.CreateStatement.ExecuteQuery(SQL),
1815 ConstructVirtualResultSet(TableColPrivColumnsDynArray));
1819 Gets a description of the access rights for each table available
1820 in a catalog. Note that a table privilege applies to one or
1821 more columns in the table. It would be wrong to assume that
1822 this priviledge applies to all columns (this may be true for
1823 some systems but is not true for all.)
1825 <P>Only privileges matching the schema and table name
1826 criteria are returned. They are ordered by TABLE_SCHEM,
1827 TABLE_NAME, and PRIVILEGE.
1829 <P>Each privilige description has the following columns:
1831 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1832 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1833 <LI><B>TABLE_NAME</B> String => table name
1834 <LI><B>GRANTOR</B> => grantor of access (may be null)
1835 <LI><B>GRANTEE</B> String => grantee of access
1836 <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1837 INSERT, UPDATE, REFRENCES, ...)
1838 <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1839 to grant to others; "NO" if not; null if unknown
1842 @param catalog a catalog name; "" retrieves those without a
1843 catalog; null means drop catalog name from the selection criteria
1844 @param schemaPattern a schema name pattern; "" retrieves those
1846 @param tableNamePattern a table name pattern
1847 @return <code>ResultSet</code> - each row is a table privilege description
1848 @see #getSearchStringEscape
1850 function TZOracleDatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;
1851 const SchemaPattern: string; const TableNamePattern: string): IZResultSet;
1854 OwnerCondition,TableCondition: String;
1856 function CreateWhere: String;
1859 If OwnerCondition <> '' then
1860 Result := OwnerCondition;
1861 If TableCondition <> '' then
1862 If Result <> '' then
1863 Result := Result + ' AND ' + TableCondition
1865 Result := TableCondition;
1866 If Result <> '' then
1867 Result := ' Where ' + Result;
1871 OwnerCondition := ConstructNameCondition(SchemaPattern,'TABLE_SCHEMA');
1872 TableCondition := ConstructNameCondition(TableNamePattern,'TABLE_NAME');
1873 SQL := 'SELECT NULL AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME,'
1874 + ' GRANTOR, GRANTEE, PRIVILEGE, GRANTABLE AS IS_GRANTABLE'
1875 + ' FROM SYS.ALL_TAB_PRIVS '
1878 Result := CopyToVirtualResultSet(
1879 GetConnection.CreateStatement.ExecuteQuery(SQL),
1880 ConstructVirtualResultSet(TablePrivColumnsDynArray));
1884 Gets a description of a table's primary key columns. They
1885 are ordered by COLUMN_NAME.
1887 <P>Each primary key column description has the following columns:
1889 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1890 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1891 <LI><B>TABLE_NAME</B> String => table name
1892 <LI><B>COLUMN_NAME</B> String => column name
1893 <LI><B>KEY_SEQ</B> short => sequence number within primary key
1894 <LI><B>PK_NAME</B> String => primary key name (may be null)
1897 @param catalog a catalog name; "" retrieves those without a
1898 catalog; null means drop catalog name from the selection criteria
1899 @param schema a schema name; "" retrieves those
1901 @param table a table name
1902 @return <code>ResultSet</code> - each row is a primary key column description
1903 @exception SQLException if a database access error occurs
1905 function TZOracleDatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;
1906 const Schema: string; const Table: string): IZResultSet;
1909 OwnerCondition,TableCondition: String;
1911 function CreateExtraWhere: String;
1914 If OwnerCondition <> '' then
1915 Result := OwnerCondition;
1916 If TableCondition <> '' then
1917 If Result <> '' then
1918 Result := Result + ' AND ' + TableCondition
1920 Result := TableCondition;
1921 If Result <> '' then
1922 Result := ' AND ' + Result;
1926 OwnerCondition := ConstructNameCondition(Schema,'A.OWNER');
1927 TableCondition := ConstructNameCondition(Table,'A.TABLE_NAME');
1928 SQL := 'SELECT NULL AS TABLE_CAT, A.OWNER AS TABLE_SCHEM, A.TABLE_NAME,'
1929 + ' B.COLUMN_NAME, B.COLUMN_POSITION AS KEY_SEQ, A.INDEX_NAME AS PK_NAME'
1930 + ' FROM ALL_INDEXES A, ALL_IND_COLUMNS B'
1931 + ' WHERE A.OWNER=B.INDEX_OWNER AND A.INDEX_NAME=B.INDEX_NAME'
1932 + ' AND A.TABLE_OWNER=B.TABLE_OWNER AND A.TABLE_NAME=B.TABLE_NAME'
1933 + ' AND A.UNIQUENESS=''UNIQUE'' AND A.GENERATED=''Y'''
1934 + ' AND A.INDEX_NAME LIKE ''SYS_%'''
1936 + ' ORDER BY A.INDEX_NAME, B.COLUMN_POSITION';
1938 Result := CopyToVirtualResultSet(
1939 GetConnection.CreateStatement.ExecuteQuery(SQL),
1940 ConstructVirtualResultSet(PrimaryKeyColumnsDynArray));
1944 Gets a description of a table's indices and statistics. They are
1945 ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
1947 <P>Each index column description has the following columns:
1949 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1950 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1951 <LI><B>TABLE_NAME</B> String => table name
1952 <LI><B>NON_UNIQUE</B> Boolean => Can index values be non-unique?
1953 false when TYPE is tableIndexStatistic
1954 <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);
1955 null when TYPE is tableIndexStatistic
1956 <LI><B>INDEX_NAME</B> String => index name; null when TYPE is
1958 <LI><B>TYPE</B> short => index type:
1960 <LI> tableIndexStatistic - this identifies table statistics that are
1961 returned in conjuction with a table's index descriptions
1962 <LI> tableIndexClustered - this is a clustered index
1963 <LI> tableIndexHashed - this is a hashed index
1964 <LI> tableIndexOther - this is some other style of index
1966 <LI><B>ORDINAL_POSITION</B> short => column sequence number
1967 within index; zero when TYPE is tableIndexStatistic
1968 <LI><B>COLUMN_NAME</B> String => column name; null when TYPE is
1970 <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending,
1971 "D" => descending, may be null if sort sequence is not supported;
1972 null when TYPE is tableIndexStatistic
1973 <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then
1974 this is the number of rows in the table; otherwise, it is the
1975 number of unique values in the index.
1976 <LI><B>PAGES</B> int => When TYPE is tableIndexStatisic then
1977 this is the number of pages used for the table, otherwise it
1978 is the number of pages used for the current index.
1979 <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
1983 @param catalog a catalog name; "" retrieves those without a
1984 catalog; null means drop catalog name from the selection criteria
1985 @param schema a schema name; "" retrieves those without a schema
1986 @param table a table name
1987 @param unique when true, return only indices for unique values;
1988 when false, return indices regardless of whether unique or not
1989 @param approximate when true, result is allowed to reflect approximate
1990 or out of data values; when false, results are requested to be
1992 @return <code>ResultSet</code> - each row is an index column description
1994 function TZOracleDatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;
1995 const Schema: string; const Table: string; Unique: Boolean;
1996 Approximate: Boolean): IZResultSet;
1999 OwnerCondition,TableCondition: String;
2001 function CreateExtraWhere: String;
2004 If OwnerCondition <> '' then
2005 Result := OwnerCondition;
2006 If TableCondition <> '' then
2007 If Result <> '' then
2008 Result := Result + ' AND ' + TableCondition
2010 Result := TableCondition;
2011 If Result <> '' then
2012 Result := ' AND ' + Result;
2016 OwnerCondition := ConstructNameCondition(Schema,'A.TABLE_OWNER');
2017 TableCondition := ConstructNameCondition(Table,'A.TABLE_NAME');
2018 Result:=inherited UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);
2020 SQL := 'SELECT NULL, A.OWNER, A.TABLE_NAME, A.UNIQUENESS, NULL,'
2021 + ' A.INDEX_NAME, 3, B.COLUMN_POSITION, B.COLUMN_NAME, B.DESCEND,'
2022 + ' 0, 0, NULL FROM ALL_INDEXES A, ALL_IND_COLUMNS B'
2023 + ' WHERE A.OWNER=B.INDEX_OWNER AND A.INDEX_NAME=B.INDEX_NAME'
2024 + ' AND A.TABLE_OWNER=B.TABLE_OWNER AND A.TABLE_NAME=B.TABLE_NAME'
2027 SQL := SQL + ' AND A.UNIQUENESS=''UNIQUE''';
2028 SQL := SQL + ' ORDER BY A.UNIQUENESS DESC, A.INDEX_NAME, B.COLUMN_POSITION';
2030 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
2034 Result.MoveToInsertRow;
2036 Result.UpdateNull(1);
2037 Result.UpdateString(2, GetString(2));
2038 Result.UpdateString(3, GetString(3));
2039 Result.UpdateBoolean(4,
2040 UpperCase(GetString(4)) <> 'UNIQUE');
2041 Result.UpdateNull(5);
2042 Result.UpdateString(6, GetString(6));
2043 Result.UpdateInt(7, GetInt(7));
2044 Result.UpdateInt(8, GetInt(8));
2045 Result.UpdateString(9, GetString(9));
2046 if GetString(10) = 'ASC' then
2047 Result.UpdateString(10, 'A')
2048 else Result.UpdateString(10, 'D');
2049 Result.UpdateInt(11, GetInt(11));
2050 Result.UpdateInt(12, GetInt(12));
2051 Result.UpdateNull(13);