00001 {*********************************************************}
00002 { }
00003 { Zeos Database Objects }
00004 { Sybase Database metadata information }
00005 { }
00006 { Originally written by Janos Fegyverneki }
00007 { }
00008 {*********************************************************}
00009
00010 {@********************************************************}
00011 { Copyright (c) 1999-2006 Zeos Development Group }
00012 { }
00013 { License Agreement: }
00014 { }
00015 { This library is distributed in the hope that it will be }
00016 { useful, but WITHOUT ANY WARRANTY; without even the }
00017 { implied warranty of MERCHANTABILITY or FITNESS FOR }
00018 { A PARTICULAR PURPOSE. See the GNU Lesser General }
00019 { Public License for more details. }
00020 { }
00021 { The source code of the ZEOS Libraries and packages are }
00022 { distributed under the Library GNU General Public }
00023 { License (see the file COPYING / COPYING.ZEOS) }
00024 { with the following modification: }
00025 { As a special exception, the copyright holders of this }
00026 { library give you permission to link this library with }
00027 { independent modules to produce an executable, }
00028 { regardless of the license terms of these independent }
00029 { modules, and to copy and distribute the resulting }
00030 { executable under terms of your choice, provided that }
00031 { you also meet, for each linked independent module, }
00032 { the terms and conditions of the license of that module. }
00033 { An independent module is a module which is not derived }
00034 { from or based on this library. If you modify this }
00035 { library, you may extend this exception to your version }
00036 { of the library, but you are not obligated to do so. }
00037 { If you do not wish to do so, delete this exception }
00038 { statement from your version. }
00039 { }
00040 { }
00041 { The project web site is located on: }
00042 { http:
00043 { http:
00044 { svn:
00045 { }
00046 { http:
00047 { http:
00048 { }
00049 { }
00050 { }
00051 { Zeos Development Group. }
00052 {********************************************************@}
00053
00054 unit ZDbcDbLibSybaseMetadata;
00055
00056 interface
00057
00058 {$I ZDbc.inc}
00059
00060 uses
00061 {$IFNDEF VER130BELOW}
00062 Types,
00063 {$ENDIF}
00064 Classes, SysUtils, ZSysUtils, ZDbcIntfs, ZDbcMetadata,
00065 ZCompatibility, ZGenericSqlAnalyser, ZDbcConnection;
00066
00067 type
00068
00069 {** Implements Sybase Database Metadata. }
00070 TZSybaseDatabaseMetadata = class(TZAbstractDatabaseMetadata)
00071 protected
00072 function GetStatement: IZStatement;
00073 function UncachedGetTables(const Catalog: string; const SchemaPattern: string;
00074 const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;
00075 function UncachedGetSchemas: IZResultSet; override;
00076 function UncachedGetCatalogs: IZResultSet; override;
00077 function UncachedGetTableTypes: IZResultSet; override;
00078 function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;
00079 const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;
00080 function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;
00081 const TableNamePattern: string): IZResultSet; override;
00082 function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;
00083 const Table: string; const ColumnNamePattern: string): IZResultSet; override;
00084 function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;
00085 const Table: string): IZResultSet; override;
00086 function UncachedGetImportedKeys(const Catalog: string; const Schema: string;
00087 const Table: string): IZResultSet; override;
00088 function UncachedGetExportedKeys(const Catalog: string; const Schema: string;
00089 const Table: string): IZResultSet; override;
00090 function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;
00091 const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;
00092 const ForeignTable: string): IZResultSet; override;
00093 function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;
00094 Unique: Boolean; Approximate: Boolean): IZResultSet; override;
00095
00096
00097 function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;
00098 const ProcedureNamePattern: string): IZResultSet; override;
00099 function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;
00100 const ProcedureNamePattern: string; const ColumnNamePattern: string):
00101 IZResultSet; override;
00102 function UncachedGetVersionColumns(const Catalog: string; const Schema: string;
00103 const Table: string): IZResultSet; override;
00104 function UncachedGetTypeInfo: IZResultSet; override;
00105 function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;
00106 const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;
00107 public
00108 constructor Create(Connection: TZAbstractConnection; Url: string;
00109 Info: TStrings);
00110 destructor Destroy; override;
00111
00112 function GetDatabaseProductName: string; override;
00113 function GetDatabaseProductVersion: string; override;
00114 function GetDriverName: string; override;
00115 function GetDriverMajorVersion: Integer; override;
00116 function GetDriverMinorVersion: Integer; override;
00117 function UsesLocalFilePerTable: Boolean; override;
00118 function SupportsMixedCaseIdentifiers: Boolean; override;
00119 function StoresUpperCaseIdentifiers: Boolean; override;
00120 function StoresLowerCaseIdentifiers: Boolean; override;
00121 function StoresMixedCaseIdentifiers: Boolean; override;
00122 function SupportsMixedCaseQuotedIdentifiers: Boolean; override;
00123 function StoresUpperCaseQuotedIdentifiers: Boolean; override;
00124 function StoresLowerCaseQuotedIdentifiers: Boolean; override;
00125 function StoresMixedCaseQuotedIdentifiers: Boolean; override;
00126 function GetIdentifierQuoteString: string; override;
00127 function GetSQLKeywords: string; override;
00128 function GetNumericFunctions: string; override;
00129 function GetStringFunctions: string; override;
00130 function GetSystemFunctions: string; override;
00131 function GetTimeDateFunctions: string; override;
00132 function GetSearchStringEscape: string; override;
00133 function GetExtraNameCharacters: string; override;
00134
00135 function SupportsExpressionsInOrderBy: Boolean; override;
00136 function SupportsOrderByUnrelated: Boolean; override;
00137 function SupportsGroupBy: Boolean; override;
00138 function SupportsGroupByUnrelated: Boolean; override;
00139 function SupportsGroupByBeyondSelect: Boolean; override;
00140 function SupportsIntegrityEnhancementFacility: Boolean; override;
00141 function GetSchemaTerm: string; override;
00142 function GetProcedureTerm: string; override;
00143 function GetCatalogTerm: string; override;
00144 function GetCatalogSeparator: string; override;
00145 function SupportsSchemasInDataManipulation: Boolean; override;
00146 function SupportsSchemasInProcedureCalls: Boolean; override;
00147 function SupportsSchemasInTableDefinitions: Boolean; override;
00148 function SupportsSchemasInIndexDefinitions: Boolean; override;
00149 function SupportsSchemasInPrivilegeDefinitions: Boolean; override;
00150 function SupportsCatalogsInDataManipulation: Boolean; override;
00151 function SupportsCatalogsInProcedureCalls: Boolean; override;
00152 function SupportsCatalogsInTableDefinitions: Boolean; override;
00153 function SupportsCatalogsInIndexDefinitions: Boolean; override;
00154 function SupportsCatalogsInPrivilegeDefinitions: Boolean; override;
00155 function SupportsPositionedDelete: Boolean; override;
00156 function SupportsPositionedUpdate: Boolean; override;
00157 function SupportsSelectForUpdate: Boolean; override;
00158 function SupportsStoredProcedures: Boolean; override;
00159 function SupportsSubqueriesInComparisons: Boolean; override;
00160 function SupportsSubqueriesInExists: Boolean; override;
00161 function SupportsSubqueriesInIns: Boolean; override;
00162 function SupportsSubqueriesInQuantifieds: Boolean; override;
00163 function SupportsCorrelatedSubqueries: Boolean; override;
00164 function SupportsUnion: Boolean; override;
00165 function SupportsUnionAll: Boolean; override;
00166 function SupportsOpenCursorsAcrossCommit: Boolean; override;
00167 function SupportsOpenCursorsAcrossRollback: Boolean; override;
00168 function SupportsOpenStatementsAcrossCommit: Boolean; override;
00169 function SupportsOpenStatementsAcrossRollback: Boolean; override;
00170
00171 function GetMaxBinaryLiteralLength: Integer; override;
00172 function GetMaxCharLiteralLength: Integer; override;
00173 function GetMaxColumnNameLength: Integer; override;
00174 function GetMaxColumnsInGroupBy: Integer; override;
00175 function GetMaxColumnsInIndex: Integer; override;
00176 function GetMaxColumnsInOrderBy: Integer; override;
00177 function GetMaxColumnsInSelect: Integer; override;
00178 function GetMaxColumnsInTable: Integer; override;
00179 function GetMaxConnections: Integer; override;
00180 function GetMaxCursorNameLength: Integer; override;
00181 function GetMaxIndexLength: Integer; override;
00182 function GetMaxSchemaNameLength: Integer; override;
00183 function GetMaxProcedureNameLength: Integer; override;
00184 function GetMaxCatalogNameLength: Integer; override;
00185 function GetMaxRowSize: Integer; override;
00186 function DoesMaxRowSizeIncludeBlobs: Boolean; override;
00187 function GetMaxStatementLength: Integer; override;
00188 function GetMaxStatements: Integer; override;
00189 function GetMaxTableNameLength: Integer; override;
00190 function GetMaxTablesInSelect: Integer; override;
00191 function GetMaxUserNameLength: Integer; override;
00192
00193 function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;
00194 function SupportsTransactions: Boolean; override;
00195 function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):
00196 Boolean; override;
00197 function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;
00198 function SupportsDataManipulationTransactionsOnly: Boolean; override;
00199 function DataDefinitionCausesTransactionCommit: Boolean; override;
00200 function DataDefinitionIgnoredInTransactions: Boolean; override;
00201
00202 function SupportsResultSetType(_Type: TZResultSetType): Boolean; override;
00203 function SupportsResultSetConcurrency(_Type: TZResultSetType;
00204 Concurrency: TZResultSetConcurrency): Boolean; override;
00205 end;
00206
00207 implementation
00208
00209 uses ZDbcUtils, ZDbcDbLibUtils;
00210
00211 { TZSybaseDatabaseMetadata }
00212
00213 {**
00214 Constructs this object and assignes the main properties.
00215 @param Connection a database connection object.
00216 @param Url a database connection url string.
00217 @param Info an extra connection properties.
00218 }
00219 constructor TZSybaseDatabaseMetadata.Create(Connection: TZAbstractConnection;
00220 Url: string; Info: TStrings);
00221 begin
00222 inherited Create(Connection, Url, Info);
00223 end;
00224
00225 {**
00226 Destroys this object and cleanups the memory.
00227 }
00228 destructor TZSybaseDatabaseMetadata.Destroy;
00229 begin
00230 inherited Destroy;
00231 end;
00232
00233
00234
00235
00236 {**
00237 What's the name of this database product?
00238 @return database product name
00239 }
00240 function TZSybaseDatabaseMetadata.GetDatabaseProductName: string;
00241 begin
00242 Result := 'Sybase';
00243 end;
00244
00245 {**
00246 What's the version of this database product?
00247 @return database version
00248 }
00249 function TZSybaseDatabaseMetadata.GetDatabaseProductVersion: string;
00250 begin
00251 Result := '12+';
00252 end;
00253
00254 {**
00255 What's the name of this JDBC driver?
00256 @return JDBC driver name
00257 }
00258 function TZSybaseDatabaseMetadata.GetDriverName: string;
00259 begin
00260 Result := 'Zeos Database Connectivity Driver for Sybase ASE Server';
00261 end;
00262
00263 {**
00264 What's this JDBC driver's major version number?
00265 @return JDBC driver major version
00266 }
00267 function TZSybaseDatabaseMetadata.GetDriverMajorVersion: Integer;
00268 begin
00269 Result := 1;
00270 end;
00271
00272 {**
00273 What's this JDBC driver's minor version number?
00274 @return JDBC driver minor version number
00275 }
00276 function TZSybaseDatabaseMetadata.GetDriverMinorVersion: Integer;
00277 begin
00278 Result := 0;
00279 end;
00280
00281 {**
00282 Does the database use a file for each table?
00283 @return true if the database uses a local file for each table
00284 }
00285 function TZSybaseDatabaseMetadata.UsesLocalFilePerTable: Boolean;
00286 begin
00287 Result := False;
00288 end;
00289
00290 {**
00291 Does the database treat mixed case unquoted SQL identifiers as
00292 case sensitive and as a result store them in mixed case?
00293 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return false.
00294 @return <code>true</code> if so; <code>false</code> otherwise
00295 }
00296 function TZSybaseDatabaseMetadata.SupportsMixedCaseIdentifiers: Boolean;
00297 begin
00298 Result := False;
00299 end;
00300
00301 {**
00302 Does the database treat mixed case unquoted SQL identifiers as
00303 case insensitive and store them in upper case?
00304 @return <code>true</code> if so; <code>false</code> otherwise
00305 }
00306 function TZSybaseDatabaseMetadata.StoresUpperCaseIdentifiers: Boolean;
00307 begin
00308 Result := True;
00309 end;
00310
00311 {**
00312 Does the database treat mixed case unquoted SQL identifiers as
00313 case insensitive and store them in lower case?
00314 @return <code>true</code> if so; <code>false</code> otherwise
00315 }
00316 function TZSybaseDatabaseMetadata.StoresLowerCaseIdentifiers: Boolean;
00317 begin
00318 Result := True;
00319 end;
00320
00321 {**
00322 Does the database treat mixed case unquoted SQL identifiers as
00323 case insensitive and store them in mixed case?
00324 @return <code>true</code> if so; <code>false</code> otherwise
00325 }
00326 function TZSybaseDatabaseMetadata.StoresMixedCaseIdentifiers: Boolean;
00327 begin
00328 Result := True;
00329 end;
00330
00331 {**
00332 Does the database treat mixed case quoted SQL identifiers as
00333 case sensitive and as a result store them in mixed case?
00334 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.
00335 @return <code>true</code> if so; <code>false</code> otherwise
00336 }
00337 function TZSybaseDatabaseMetadata.SupportsMixedCaseQuotedIdentifiers: Boolean;
00338 begin
00339 Result := True;
00340 end;
00341
00342 {**
00343 Does the database treat mixed case quoted SQL identifiers as
00344 case insensitive and store them in upper case?
00345 @return <code>true</code> if so; <code>false</code> otherwise
00346 }
00347 function TZSybaseDatabaseMetadata.StoresUpperCaseQuotedIdentifiers: Boolean;
00348 begin
00349 Result := True;
00350 end;
00351
00352 {**
00353 Does the database treat mixed case quoted SQL identifiers as
00354 case insensitive and store them in lower case?
00355 @return <code>true</code> if so; <code>false</code> otherwise
00356 }
00357 function TZSybaseDatabaseMetadata.StoresLowerCaseQuotedIdentifiers: Boolean;
00358 begin
00359 Result := True;
00360 end;
00361
00362 {**
00363 Does the database treat mixed case quoted SQL identifiers as
00364 case insensitive and store them in mixed case?
00365 @return <code>true</code> if so; <code>false</code> otherwise
00366 }
00367 function TZSybaseDatabaseMetadata.StoresMixedCaseQuotedIdentifiers: Boolean;
00368 begin
00369 Result := True;
00370 end;
00371
00372 {**
00373 What's the string used to quote SQL identifiers?
00374 This returns a space " " if identifier quoting isn't supported.
00375 A JDBC Compliant<sup><font size=-2>TM</font></sup>
00376 driver always uses a double quote character.
00377 @return the quoting string
00378 }
00379 function TZSybaseDatabaseMetadata.GetIdentifierQuoteString: string;
00380 begin
00381 Result := '"';
00382 end;
00383
00384 {**
00385 Gets a comma-separated list of all a database's SQL keywords
00386 that are NOT also SQL92 keywords.
00387 @return the list
00388 }
00389 function TZSybaseDatabaseMetadata.GetSQLKeywords: string;
00390 begin
00391 { TODO -ofjanos -cAPI : SQL Keywords that are not SQL92 compliant }
00392 Result := '';
00393 end;
00394
00395 {**
00396 Gets a comma-separated list of math functions. These are the
00397 X/Open CLI math function names used in the JDBC function escape
00398 clause.
00399 @return the list
00400 }
00401 function TZSybaseDatabaseMetadata.GetNumericFunctions: string;
00402 begin
00403 Result := 'ABS,ACOS,ASIN,ATAN,ATN2,CEILING,COS,COT,DEGREES,EXP,FLOOR,LOG,LOG10,'+
00404 'PI,POWER,RADIANS,RAND,ROUND,SIGN,SIN,SQUARE,SQRT,TAN';
00405 end;
00406
00407 {**
00408 Gets a comma-separated list of string functions. These are the
00409 X/Open CLI string function names used in the JDBC function escape
00410 clause.
00411 @return the list
00412 }
00413 function TZSybaseDatabaseMetadata.GetStringFunctions: string;
00414 begin
00415 Result := 'ASCII,CHAR,CHARINDEX,DIFFERENCE,LEFT,LEN,LOWER,LTRIM,NCHAR,PATINDEX,'+
00416 'REPLACE,QUOTENAME,REPLICATE,REVERSE,RIGHT,RTRIM,SOUNDEX,SPACE,STR,'+
00417 'STUFF,SUBSTRING,UNICODE,UPPER';
00418 end;
00419
00420 {**
00421 Gets a comma-separated list of system functions. These are the
00422 X/Open CLI system function names used in the JDBC function escape
00423 clause.
00424 @return the list
00425 }
00426 function TZSybaseDatabaseMetadata.GetSystemFunctions: string;
00427 begin
00428 Result := 'APP_NAME,CASE,CAST,CONVERT,COALESCE,CURRENT_TIMESTAMP,CURRENT_USER,'+
00429 'DATALENGTH,@@ERROR,FORMATMESSAGE,GETANSINULL,HOST_ID,HOST_NAME,'+
00430 'IDENT_INCR,IDENT_SEED,@@IDENTITY,IDENTITY,ISDATE,ISNULL,ISNUMERIC,'+
00431 'NEWID,NULLIF,PARSENAME,PERMISSIONS,@@ROWCOUNT,SESSION_USER,STATS_DATE,'+
00432 'SYSTEM_USER,@@TRANCOUNT,USER_NAME';
00433 end;
00434
00435 {**
00436 Gets a comma-separated list of time and date functions.
00437 @return the list
00438 }
00439 function TZSybaseDatabaseMetadata.GetTimeDateFunctions: string;
00440 begin
00441 Result := 'DATEADD,DATEDIFF,DATENAME,DATEPART,DAY,GETDATE,MONTH,YEAR';
00442 end;
00443
00444 {**
00445 Gets the string that can be used to escape wildcard characters.
00446 This is the string that can be used to escape '_' or '%' in
00447 the string pattern style catalog search parameters.
00448
00449 <P>The '_' character represents any single character.
00450 <P>The '%' character represents any sequence of zero or
00451 more characters.
00452
00453 @return the string used to escape wildcard characters
00454 }
00455 function TZSybaseDatabaseMetadata.GetSearchStringEscape: string;
00456 begin
00457 { TODO -ofjanos -cgeneral :
00458 In sql server this must be specified as the parameter of like.
00459 example: WHERE ColumnA LIKE '%5/%%' ESCAPE '/' }
00460 Result := '/';
00461 end;
00462
00463 {**
00464 Gets all the "extra" characters that can be used in unquoted
00465 identifier names (those beyond a-z, A-Z, 0-9 and _).
00466 @return the string containing the extra characters
00467 }
00468 function TZSybaseDatabaseMetadata.GetExtraNameCharacters: string;
00469 begin
00470 Result := '@$#';
00471 end;
00472
00473 //--------------------------------------------------------------------
00474 // Functions describing which features are supported.
00475
00476 {**
00477 Are expressions in "ORDER BY" lists supported?
00478 @return <code>true</code> if so; <code>false</code> otherwise
00479 }
00480 function TZSybaseDatabaseMetadata.SupportsExpressionsInOrderBy: Boolean;
00481 begin
00482 Result := True;
00483 end;
00484
00485 {**
00486 Can an "ORDER BY" clause use columns not in the SELECT statement?
00487 @return <code>true</code> if so; <code>false</code> otherwise
00488 }
00489 function TZSybaseDatabaseMetadata.SupportsOrderByUnrelated: Boolean;
00490 begin
00491 Result := True;
00492 end;
00493
00494 {**
00495 Is some form of "GROUP BY" clause supported?
00496 @return <code>true</code> if so; <code>false</code> otherwise
00497 }
00498 function TZSybaseDatabaseMetadata.SupportsGroupBy: Boolean;
00499 begin
00500 Result := True;
00501 end;
00502
00503 {**
00504 Can a "GROUP BY" clause use columns not in the SELECT?
00505 @return <code>true</code> if so; <code>false</code> otherwise
00506 }
00507 function TZSybaseDatabaseMetadata.SupportsGroupByUnrelated: Boolean;
00508 begin
00509 Result := True;
00510 end;
00511
00512 {**
00513 Can a "GROUP BY" clause add columns not in the SELECT
00514 provided it specifies all the columns in the SELECT?
00515 @return <code>true</code> if so; <code>false</code> otherwise
00516 }
00517 function TZSybaseDatabaseMetadata.SupportsGroupByBeyondSelect: Boolean;
00518 begin
00519 Result := True;
00520 end;
00521
00522 {**
00523 Is the SQL Integrity Enhancement Facility supported?
00524 @return <code>true</code> if so; <code>false</code> otherwise
00525 }
00526 function TZSybaseDatabaseMetadata.SupportsIntegrityEnhancementFacility: Boolean;
00527 begin
00528 Result := False;
00529 end;
00530
00531 {**
00532 What's the database vendor's preferred term for "schema"?
00533 @return the vendor term
00534 }
00535 function TZSybaseDatabaseMetadata.GetSchemaTerm: string;
00536 begin
00537 Result := 'owner';
00538 end;
00539
00540 {**
00541 What's the database vendor's preferred term for "procedure"?
00542 @return the vendor term
00543 }
00544 function TZSybaseDatabaseMetadata.GetProcedureTerm: string;
00545 begin
00546 Result := 'procedure';
00547 end;
00548
00549 {**
00550 What's the database vendor's preferred term for "catalog"?
00551 @return the vendor term
00552 }
00553 function TZSybaseDatabaseMetadata.GetCatalogTerm: string;
00554 begin
00555 Result := 'database';
00556 end;
00557
00558 {**
00559 What's the separator between catalog and table name?
00560 @return the separator string
00561 }
00562 function TZSybaseDatabaseMetadata.GetCatalogSeparator: string;
00563 begin
00564 Result := '.';
00565 end;
00566
00567 {**
00568 Can a schema name be used in a data manipulation statement?
00569 @return <code>true</code> if so; <code>false</code> otherwise
00570 }
00571 function TZSybaseDatabaseMetadata.SupportsSchemasInDataManipulation: Boolean;
00572 begin
00573 Result := True;
00574 end;
00575
00576 {**
00577 Can a schema name be used in a procedure call statement?
00578 @return <code>true</code> if so; <code>false</code> otherwise
00579 }
00580 function TZSybaseDatabaseMetadata.SupportsSchemasInProcedureCalls: Boolean;
00581 begin
00582 Result := True;
00583 end;
00584
00585 {**
00586 Can a schema name be used in a table definition statement?
00587 @return <code>true</code> if so; <code>false</code> otherwise
00588 }
00589 function TZSybaseDatabaseMetadata.SupportsSchemasInTableDefinitions: Boolean;
00590 begin
00591 Result := True;
00592 end;
00593
00594 {**
00595 Can a schema name be used in an index definition statement?
00596 @return <code>true</code> if so; <code>false</code> otherwise
00597 }
00598 function TZSybaseDatabaseMetadata.SupportsSchemasInIndexDefinitions: Boolean;
00599 begin
00600 Result := True;
00601 end;
00602
00603 {**
00604 Can a schema name be used in a privilege definition statement?
00605 @return <code>true</code> if so; <code>false</code> otherwise
00606 }
00607 function TZSybaseDatabaseMetadata.SupportsSchemasInPrivilegeDefinitions: Boolean;
00608 begin
00609 Result := True;
00610 end;
00611
00612 {**
00613 Can a catalog name be used in a data manipulation statement?
00614 @return <code>true</code> if so; <code>false</code> otherwise
00615 }
00616 function TZSybaseDatabaseMetadata.SupportsCatalogsInDataManipulation: Boolean;
00617 begin
00618 Result := True;
00619 end;
00620
00621 {**
00622 Can a catalog name be used in a procedure call statement?
00623 @return <code>true</code> if so; <code>false</code> otherwise
00624 }
00625 function TZSybaseDatabaseMetadata.SupportsCatalogsInProcedureCalls: Boolean;
00626 begin
00627 Result := True;
00628 end;
00629
00630 {**
00631 Can a catalog name be used in a table definition statement?
00632 @return <code>true</code> if so; <code>false</code> otherwise
00633 }
00634 function TZSybaseDatabaseMetadata.SupportsCatalogsInTableDefinitions: Boolean;
00635 begin
00636 Result := True;
00637 end;
00638
00639 {**
00640 Can a catalog name be used in an index definition statement?
00641 @return <code>true</code> if so; <code>false</code> otherwise
00642 }
00643 function TZSybaseDatabaseMetadata.SupportsCatalogsInIndexDefinitions: Boolean;
00644 begin
00645 Result := True;
00646 end;
00647
00648 {**
00649 Can a catalog name be used in a privilege definition statement?
00650 @return <code>true</code> if so; <code>false</code> otherwise
00651 }
00652 function TZSybaseDatabaseMetadata.SupportsCatalogsInPrivilegeDefinitions: Boolean;
00653 begin
00654 Result := True;
00655 end;
00656
00657 {**
00658 Is positioned DELETE supported?
00659 @return <code>true</code> if so; <code>false</code> otherwise
00660 }
00661 function TZSybaseDatabaseMetadata.SupportsPositionedDelete: Boolean;
00662 begin
00663 //CURRENT OF
00664 //Specifies that the DELETE is done at the current position of the specified cursor.
00665 Result := True;
00666 end;
00667
00668 {**
00669 Is positioned UPDATE supported?
00670 @return <code>true</code> if so; <code>false</code> otherwise
00671 }
00672 function TZSybaseDatabaseMetadata.SupportsPositionedUpdate: Boolean;
00673 begin
00674 Result := True;
00675 end;
00676
00677 {**
00678 Is SELECT for UPDATE supported?
00679 @return <code>true</code> if so; <code>false</code> otherwise
00680 }
00681 function TZSybaseDatabaseMetadata.SupportsSelectForUpdate: Boolean;
00682 begin
00683 Result := True;
00684 end;
00685
00686 {**
00687 Are stored procedure calls using the stored procedure escape
00688 syntax supported?
00689 @return <code>true</code> if so; <code>false</code> otherwise
00690 }
00691 function TZSybaseDatabaseMetadata.SupportsStoredProcedures: Boolean;
00692 begin
00693 Result := True;
00694 end;
00695
00696 {**
00697 Are subqueries in comparison expressions supported?
00698 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
00699 @return <code>true</code> if so; <code>false</code> otherwise
00700 }
00701 function TZSybaseDatabaseMetadata.SupportsSubqueriesInComparisons: Boolean;
00702 begin
00703 Result := True;
00704 end;
00705
00706 {**
00707 Are subqueries in 'exists' expressions supported?
00708 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
00709 @return <code>true</code> if so; <code>false</code> otherwise
00710 }
00711 function TZSybaseDatabaseMetadata.SupportsSubqueriesInExists: Boolean;
00712 begin
00713 Result := True;
00714 end;
00715
00716 {**
00717 Are subqueries in 'in' statements supported?
00718 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
00719 @return <code>true</code> if so; <code>false</code> otherwise
00720 }
00721 function TZSybaseDatabaseMetadata.SupportsSubqueriesInIns: Boolean;
00722 begin
00723 Result := True;
00724 end;
00725
00726 {**
00727 Are subqueries in quantified expressions supported?
00728 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
00729 @return <code>true</code> if so; <code>false</code> otherwise
00730 }
00731 function TZSybaseDatabaseMetadata.SupportsSubqueriesInQuantifieds: Boolean;
00732 begin
00733 Result := True;
00734 end;
00735
00736 {**
00737 Are correlated subqueries supported?
00738 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
00739 @return <code>true</code> if so; <code>false</code> otherwise
00740 }
00741 function TZSybaseDatabaseMetadata.SupportsCorrelatedSubqueries: Boolean;
00742 begin
00743 Result := True;
00744 end;
00745
00746 {**
00747 Is SQL UNION supported?
00748 @return <code>true</code> if so; <code>false</code> otherwise
00749 }
00750 function TZSybaseDatabaseMetadata.SupportsUnion: Boolean;
00751 begin
00752 Result := True;
00753 end;
00754
00755 {**
00756 Is SQL UNION ALL supported?
00757 @return <code>true</code> if so; <code>false</code> otherwise
00758 }
00759 function TZSybaseDatabaseMetadata.SupportsUnionAll: Boolean;
00760 begin
00761 Result := True;
00762 end;
00763
00764 {**
00765 Can cursors remain open across commits?
00766 @return <code>true</code> if cursors always remain open;
00767 <code>false</code> if they might not remain open
00768 }
00769 function TZSybaseDatabaseMetadata.SupportsOpenCursorsAcrossCommit: Boolean;
00770 begin
00771 Result := True;
00772 end;
00773
00774 {**
00775 Can cursors remain open across rollbacks?
00776 @return <code>true</code> if cursors always remain open;
00777 <code>false</code> if they might not remain open
00778 }
00779 function TZSybaseDatabaseMetadata.SupportsOpenCursorsAcrossRollback: Boolean;
00780 begin
00781 Result := True;
00782 end;
00783
00784 {**
00785 Can statements remain open across commits?
00786 @return <code>true</code> if statements always remain open;
00787 <code>false</code> if they might not remain open
00788 }
00789 function TZSybaseDatabaseMetadata.SupportsOpenStatementsAcrossCommit: Boolean;
00790 begin
00791 Result := False;
00792 end;
00793
00794 {**
00795 Can statements remain open across rollbacks?
00796 @return <code>true</code> if statements always remain open;
00797 <code>false</code> if they might not remain open
00798 }
00799 function TZSybaseDatabaseMetadata.SupportsOpenStatementsAcrossRollback: Boolean;
00800 begin
00801 Result := False;
00802 end;
00803
00804 //----------------------------------------------------------------------
00805 // The following group of methods exposes various limitations
00806 // based on the target database with the current driver.
00807 // Unless otherwise specified, a result of zero means there is no
00808 // limit, or the limit is not known.
00809
00810 {**
00811 How many hex characters can you have in an inline binary literal?
00812 @return max binary literal length in hex characters;
00813 a result of zero means that there is no limit or the limit is not known
00814 }
00815 function TZSybaseDatabaseMetadata.GetMaxBinaryLiteralLength: Integer;
00816 begin
00817 Result := 16000;
00818 end;
00819
00820 {**
00821 What's the max length for a character literal?
00822 @return max literal length;
00823 a result of zero means that there is no limit or the limit is not known
00824 }
00825 function TZSybaseDatabaseMetadata.GetMaxCharLiteralLength: Integer;
00826 begin
00827 Result := 8000;
00828 end;
00829
00830 {**
00831 What's the limit on column name length?
00832 @return max column name length;
00833 a result of zero means that there is no limit or the limit is not known
00834 }
00835 function TZSybaseDatabaseMetadata.GetMaxColumnNameLength: Integer;
00836 begin
00837 Result := 128;
00838 end;
00839
00840 {**
00841 What's the maximum number of columns in a "GROUP BY" clause?
00842 @return max number of columns;
00843 a result of zero means that there is no limit or the limit is not known
00844 }
00845 function TZSybaseDatabaseMetadata.GetMaxColumnsInGroupBy: Integer;
00846 begin
00847 Result := 0;
00848 end;
00849
00850 {**
00851 What's the maximum number of columns allowed in an index?
00852 @return max number of columns;
00853 a result of zero means that there is no limit or the limit is not known
00854 }
00855 function TZSybaseDatabaseMetadata.GetMaxColumnsInIndex: Integer;
00856 begin
00857 Result := 16;
00858 end;
00859
00860 {**
00861 What's the maximum number of columns in an "ORDER BY" clause?
00862 @return max number of columns;
00863 a result of zero means that there is no limit or the limit is not known
00864 }
00865 function TZSybaseDatabaseMetadata.GetMaxColumnsInOrderBy: Integer;
00866 begin
00867 Result := 0;
00868 end;
00869
00870 {**
00871 What's the maximum number of columns in a "SELECT" list?
00872 @return max number of columns;
00873 a result of zero means that there is no limit or the limit is not known
00874 }
00875 function TZSybaseDatabaseMetadata.GetMaxColumnsInSelect: Integer;
00876 begin
00877 Result := 4096;
00878 end;
00879
00880 {**
00881 What's the maximum number of columns in a table?
00882 @return max number of columns;
00883 a result of zero means that there is no limit or the limit is not known
00884 }
00885 function TZSybaseDatabaseMetadata.GetMaxColumnsInTable: Integer;
00886 begin
00887 Result := 1024;
00888 end;
00889
00890 {**
00891 How many active connections can we have at a time to this database?
00892 @return max number of active connections;
00893 a result of zero means that there is no limit or the limit is not known
00894 }
00895 function TZSybaseDatabaseMetadata.GetMaxConnections: Integer;
00896 begin
00897 Result := 0;
00898 end;
00899
00900 {**
00901 What's the maximum cursor name length?
00902 @return max cursor name length in bytes;
00903 a result of zero means that there is no limit or the limit is not known
00904 }
00905 function TZSybaseDatabaseMetadata.GetMaxCursorNameLength: Integer;
00906 begin
00907 Result := 128;
00908 end;
00909
00910 {**
00911 Retrieves the maximum number of bytes for an index, including all
00912 of the parts of the index.
00913 @return max index length in bytes, which includes the composite of all
00914 the constituent parts of the index;
00915 a result of zero means that there is no limit or the limit is not known
00916 }
00917 function TZSybaseDatabaseMetadata.GetMaxIndexLength: Integer;
00918 begin
00919 Result := 900;
00920 end;
00921
00922 {**
00923 What's the maximum length allowed for a schema name?
00924 @return max name length in bytes;
00925 a result of zero means that there is no limit or the limit is not known
00926 }
00927 function TZSybaseDatabaseMetadata.GetMaxSchemaNameLength: Integer;
00928 begin
00929 Result := 128;
00930 end;
00931
00932 {**
00933 What's the maximum length of a procedure name?
00934 @return max name length in bytes;
00935 a result of zero means that there is no limit or the limit is not known
00936 }
00937 function TZSybaseDatabaseMetadata.GetMaxProcedureNameLength: Integer;
00938 begin
00939 Result := 128;
00940 end;
00941
00942 {**
00943 What's the maximum length of a catalog name?
00944 @return max name length in bytes;
00945 a result of zero means that there is no limit or the limit is not known
00946 }
00947 function TZSybaseDatabaseMetadata.GetMaxCatalogNameLength: Integer;
00948 begin
00949 Result := 128;
00950 end;
00951
00952 {**
00953 What's the maximum length of a single row?
00954 @return max row size in bytes;
00955 a result of zero means that there is no limit or the limit is not known
00956 }
00957 function TZSybaseDatabaseMetadata.GetMaxRowSize: Integer;
00958 begin
00959 Result := 8060;
00960 end;
00961
00962 {**
00963 Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY
00964 blobs?
00965 @return <code>true</code> if so; <code>false</code> otherwise
00966 }
00967 function TZSybaseDatabaseMetadata.DoesMaxRowSizeIncludeBlobs: Boolean;
00968 begin
00969 Result := False;
00970 end;
00971
00972 {**
00973 What's the maximum length of an SQL statement?
00974 @return max length in bytes;
00975 a result of zero means that there is no limit or the limit is not known
00976 }
00977 function TZSybaseDatabaseMetadata.GetMaxStatementLength: Integer;
00978 begin
00979 Result := 0;
00980 end;
00981
00982 {**
00983 How many active statements can we have open at one time to this
00984 database?
00985 @return the maximum number of statements that can be open at one time;
00986 a result of zero means that there is no limit or the limit is not known
00987 }
00988 function TZSybaseDatabaseMetadata.GetMaxStatements: Integer;
00989 begin
00990 Result := 0;
00991 end;
00992
00993 {**
00994 What's the maximum length of a table name?
00995 @return max name length in bytes;
00996 a result of zero means that there is no limit or the limit is not known
00997 }
00998 function TZSybaseDatabaseMetadata.GetMaxTableNameLength: Integer;
00999 begin
01000 Result := 128;
01001 end;
01002
01003 {**
01004 What's the maximum number of tables in a SELECT statement?
01005 @return the maximum number of tables allowed in a SELECT statement;
01006 a result of zero means that there is no limit or the limit is not known
01007 }
01008 function TZSybaseDatabaseMetadata.GetMaxTablesInSelect: Integer;
01009 begin
01010 Result := 256;
01011 end;
01012
01013 {**
01014 What's the maximum length of a user name?
01015 @return max user name length in bytes;
01016 a result of zero means that there is no limit or the limit is not known
01017 }
01018 function TZSybaseDatabaseMetadata.GetMaxUserNameLength: Integer;
01019 begin
01020 Result := 128;
01021 end;
01022
01023 //----------------------------------------------------------------------
01024
01025 {**
01026 What's the database's default transaction isolation level? The
01027 values are defined in <code>java.sql.Connection</code>.
01028 @return the default isolation level
01029 @see Connection
01030 }
01031 function TZSybaseDatabaseMetadata.GetDefaultTransactionIsolation:
01032 TZTransactIsolationLevel;
01033 begin
01034 Result := tiReadCommitted;
01035 end;
01036
01037 {**
01038 Are transactions supported? If not, invoking the method
01039 <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.
01040 @return <code>true</code> if transactions are supported; <code>false</code> otherwise
01041 }
01042 function TZSybaseDatabaseMetadata.SupportsTransactions: Boolean;
01043 begin
01044 Result := True;
01045 end;
01046
01047 {**
01048 Does this database support the given transaction isolation level?
01049 @param level the values are defined in <code>java.sql.Connection</code>
01050 @return <code>true</code> if so; <code>false</code> otherwise
01051 @see Connection
01052 }
01053 function TZSybaseDatabaseMetadata.SupportsTransactionIsolationLevel(
01054 Level: TZTransactIsolationLevel): Boolean;
01055 begin
01056 Result := True;
01057 end;
01058
01059 {**
01060 Are both data definition and data manipulation statements
01061 within a transaction supported?
01062 @return <code>true</code> if so; <code>false</code> otherwise
01063 }
01064 function TZSybaseDatabaseMetadata.
01065 SupportsDataDefinitionAndDataManipulationTransactions: Boolean;
01066 begin
01067 Result := True;
01068 end;
01069
01070 {**
01071 Are only data manipulation statements within a transaction
01072 supported?
01073 @return <code>true</code> if so; <code>false</code> otherwise
01074 }
01075 function TZSybaseDatabaseMetadata.
01076 SupportsDataManipulationTransactionsOnly: Boolean;
01077 begin
01078 Result := False;
01079 end;
01080
01081 {**
01082 Does a data definition statement within a transaction force the
01083 transaction to commit?
01084 @return <code>true</code> if so; <code>false</code> otherwise
01085 }
01086 function TZSybaseDatabaseMetadata.DataDefinitionCausesTransactionCommit: Boolean;
01087 begin
01088 Result := False;
01089 end;
01090
01091 {**
01092 Is a data definition statement within a transaction ignored?
01093 @return <code>true</code> if so; <code>false</code> otherwise
01094 }
01095 function TZSybaseDatabaseMetadata.DataDefinitionIgnoredInTransactions: Boolean;
01096 begin
01097 Result := False;
01098 end;
01099
01100 {**
01101 Gets a description of the stored procedures available in a
01102 catalog.
01103
01104 <P>Only procedure descriptions matching the schema and
01105 procedure name criteria are returned. They are ordered by
01106 PROCEDURE_SCHEM, and PROCEDURE_NAME.
01107
01108 <P>Each procedure description has the the following columns:
01109 <OL>
01110 <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
01111 <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
01112 <LI><B>PROCEDURE_NAME</B> String => procedure name
01113 <LI> reserved for future use
01114 <LI> reserved for future use
01115 <LI> reserved for future use
01116 <LI><B>REMARKS</B> String => explanatory comment on the procedure
01117 <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:
01118 <UL>
01119 <LI> procedureResultUnknown - May return a result
01120 <LI> procedureNoResult - Does not return a result
01121 <LI> procedureReturnsResult - Returns a result
01122 </UL>
01123 </OL>
01124
01125 @param catalog a catalog name; "" retrieves those without a
01126 catalog; null means drop catalog name from the selection criteria
01127 @param schemaPattern a schema name pattern; "" retrieves those
01128 without a schema
01129 @param procedureNamePattern a procedure name pattern
01130 @return <code>ResultSet</code> - each row is a procedure description
01131 @see #getSearchStringEscape
01132 }
01133 function TZSybaseDatabaseMetadata.UncachedGetProcedures(const Catalog: string;
01134 const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;
01135 begin
01136 Result := ConstructVirtualResultSet(ProceduresColumnsDynArray);
01137
01138 with GetStatement.ExecuteQuery(
01139 Format('exec sp_jdbc_stored_procedures %s, %s, %s',
01140 [AQSNull(Catalog), AQSNull(SchemaPattern), AQSNull(ProcedureNamePattern)])) do
01141 begin
01142 while Next do
01143 begin
01144 Result.MoveToInsertRow;
01145 Result.UpdateStringByName('PROCEDURE_CAT',
01146 GetStringByName('PROCEDURE_CAT'));
01147 Result.UpdateStringByName('PROCEDURE_SCHEM',
01148 GetStringByName('PROCEDURE_SCHEM'));
01149 Result.UpdateStringByName('PROCEDURE_NAME',
01150 GetStringByName('PROCEDURE_NAME'));
01151 Result.UpdateStringByName('REMARKS',
01152 GetStringByName('REMARKS'));
01153 Result.UpdateShortByName('PROCEDURE_TYPE',
01154 GetShortByName('PROCEDURE_TYPE'));
01155 Result.InsertRow;
01156 end;
01157 Close;
01158 end;
01159 end;
01160
01161 {**
01162 Gets a description of a catalog's stored procedure parameters
01163 and result columns.
01164
01165 <P>Only descriptions matching the schema, procedure and
01166 parameter name criteria are returned. They are ordered by
01167 PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,
01168 if any, is first. Next are the parameter descriptions in call
01169 order. The column descriptions follow in column number order.
01170
01171 <P>Each row in the <code>ResultSet</code> is a parameter description or
01172 column description with the following fields:
01173 <OL>
01174 <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
01175 <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
01176 <LI><B>PROCEDURE_NAME</B> String => procedure name
01177 <LI><B>COLUMN_NAME</B> String => column/parameter name
01178 <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
01179 <UL>
01180 <LI> procedureColumnUnknown - nobody knows
01181 <LI> procedureColumnIn - IN parameter
01182 <LI> procedureColumnInOut - INOUT parameter
01183 <LI> procedureColumnOut - OUT parameter
01184 <LI> procedureColumnReturn - procedure return value
01185 <LI> procedureColumnResult - result column in <code>ResultSet</code>
01186 </UL>
01187 <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
01188 <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the
01189 type name is fully qualified
01190 <LI><B>PRECISION</B> int => precision
01191 <LI><B>LENGTH</B> int => length in bytes of data
01192 <LI><B>SCALE</B> short => scale
01193 <LI><B>RADIX</B> short => radix
01194 <LI><B>NULLABLE</B> short => can it contain NULL?
01195 <UL>
01196 <LI> procedureNoNulls - does not allow NULL values
01197 <LI> procedureNullable - allows NULL values
01198 <LI> procedureNullableUnknown - nullability unknown
01199 </UL>
01200 <LI><B>REMARKS</B> String => comment describing parameter/column
01201 </OL>
01202
01203 <P><B>Note:</B> Some databases may not return the column
01204 descriptions for a procedure. Additional columns beyond
01205 REMARKS can be defined by the database.
01206
01207 @param catalog a catalog name; "" retrieves those without a
01208 catalog; null means drop catalog name from the selection criteria
01209 @param schemaPattern a schema name pattern; "" retrieves those
01210 without a schema
01211 @param procedureNamePattern a procedure name pattern
01212 @param columnNamePattern a column name pattern
01213 @return <code>ResultSet</code> - each row describes a stored procedure parameter or
01214 column
01215 @see #getSearchStringEscape
01216 }
01217 function TZSybaseDatabaseMetadata.UncachedGetProcedureColumns(const Catalog: string;
01218 const SchemaPattern: string; const ProcedureNamePattern: string;
01219 const ColumnNamePattern: string): IZResultSet;
01220 var
01221 ProcNamePart: string;
01222 NumberPart: string;
01223 status2: Integer;
01224 begin
01225 Result := ConstructVirtualResultSet(ProceduresColColumnsDynArray);
01226
01227 with GetStatement.ExecuteQuery(
01228 Format('exec sp_jdbc_getprocedurecolumns %s, %s, %s, %s',
01229 [AQSNull(Catalog), AQSNull(SchemaPattern), AQSNull(ProcedureNamePattern), AQSNull(ColumnNamePattern)])) do
01230 begin
01231 while Next do
01232 begin
01233 Result.MoveToInsertRow;
01234 Result.UpdateStringByName('PROCEDURE_CAT',
01235 GetStringByName('PROCEDURE_CAT'));
01236 Result.UpdateStringByName('PROCEDURE_SCHEM',
01237 GetStringByName('PROCEDURE_SCHEM'));
01238 Result.UpdateStringByName('PROCEDURE_NAME',
01239 GetStringByName('PROCEDURE_NAME'));
01240 Result.UpdateStringByName('COLUMN_NAME',
01241 GetStringByName('COLUMN_NAME'));
01242 case GetShortByName('COLUMN_TYPE') of
01243 0, 1: Result.UpdateShortByName('COLUMN_TYPE', 1); //ptInput
01244 2: Result.UpdateShortByName('COLUMN_TYPE', 3); //ptInputOutput
01245 3: Result.UpdateShortByName('COLUMN_TYPE', 0); //ptUnknown
01246 4: Result.UpdateShortByName('COLUMN_TYPE', 3); //ptInputOutput
01247 5: Result.UpdateShortByName('COLUMN_TYPE', 4); //ptResult
01248 else
01249 Result.UpdateShortByName('COLUMN_TYPE', 0); //ptUnknown
01250 end;
01251 Result.UpdateShortByName('DATA_TYPE',
01252 Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'))));
01253 Result.UpdateStringByName('TYPE_NAME',
01254 GetStringByName('TYPE_NAME'));
01255 Result.UpdateIntByName('PRECISION',
01256 GetIntByName('PRECISION'));
01257 Result.UpdateIntByName('LENGTH',
01258 GetIntByName('LENGTH'));
01259 Result.UpdateShortByName('SCALE',
01260 GetShortByName('SCALE'));
01261 Result.UpdateShortByName('RADIX',
01262 GetShortByName('RADIX'));
01263 Result.UpdateShortByName('NULLABLE',
01264 GetShortByName('NULLABLE'));
01265 Result.UpdateStringByName('REMARKS',
01266 GetStringByName('REMARKS'));
01267 Result.InsertRow;
01268 end;
01269 Close;
01270 end;
01271 Result.BeforeFirst;
01272
01273 NumberPart := '1';
01274 ProcNamePart := '';
01275 if AnsiPos(';', ProcNamePart) > 0 then
01276 begin
01277 NumberPart := Copy(ProcNamePart, LastDelimiter(';', ProcNamePart) + 1,
01278 Length(ProcNamePart));
01279 if NumberPart = '' then
01280 NumberPart := '1';
01281
01282 ProcNamePart := Copy(ProcNamePart, 1, LastDelimiter(';', ProcNamePart));
01283 if ProcNamePart[Length(ProcNamePart)] = ';' then
01284 Delete(ProcNamePart, Length(ProcNamePart), 1);
01285 end;
01286 //status2 is added in sybase ASE 12.5 to store the storedprocedure parameters
01287 // input/output type this column does not exists in prior versions.
01288 // In prior versions there is no way to determine between input or output type.
01289 with GetStatement.ExecuteQuery(
01290 Format('select c.* from syscolumns c inner join sysobjects o on'
01291 + ' (o.id = c.id) where o.name = %s and c.number = %s order by colid',
01292 [AnsiQuotedStr(ProcNamePart, ''''), NumberPart])) do
01293 begin
01294 Result.Next;//Skip return parameter
01295 while Next do
01296 begin
01297 Result.Next;
01298 if FindColumn('status2') >= 1 then
01299 status2 := GetShortByName('status2')
01300 else
01301 status2 := 0;
01302 case status2 of
01303 0, 1: Result.UpdateShortByName('COLUMN_TYPE', 1); //ptInput
01304 2: Result.UpdateShortByName('COLUMN_TYPE', 3); //ptInputOutput
01305 3: Result.UpdateShortByName('COLUMN_TYPE', 0); //ptUnknown
01306 4: Result.UpdateShortByName('COLUMN_TYPE', 3); //ptInputOutput
01307 5: Result.UpdateShortByName('COLUMN_TYPE', 4); //ptResult
01308 else
01309 Result.UpdateShortByName('COLUMN_TYPE', 0); //ptUnknown
01310 end;
01311 Result.UpdateRow;
01312 end;
01313 Close;
01314 end;
01315 end;
01316
01317 {**
01318 Gets a description of tables available in a catalog.
01319
01320 <P>Only table descriptions matching the catalog, schema, table
01321 name and type criteria are returned. They are ordered by
01322 TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
01323
01324 <P>Each table description has the following columns:
01325 <OL>
01326 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
01327 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
01328 <LI><B>TABLE_NAME</B> String => table name
01329 <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
01330 "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
01331 "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
01332 <LI><B>REMARKS</B> String => explanatory comment on the table
01333 </OL>
01334
01335 <P><B>Note:</B> Some databases may not return information for
01336 all tables.
01337
01338 @param catalog a catalog name; "" retrieves those without a
01339 catalog; null means drop catalog name from the selection criteria
01340 @param schemaPattern a schema name pattern; "" retrieves those
01341 without a schema
01342 @param tableNamePattern a table name pattern
01343 @param types a list of table types to include; null returns all types
01344 @return <code>ResultSet</code> - each row is a table description
01345 @see #getSearchStringEscape
01346 }
01347 function TZSybaseDatabaseMetadata.UncachedGetTables(const Catalog: string;
01348 const SchemaPattern: string; const TableNamePattern: string;
01349 const Types: TStringDynArray): IZResultSet;
01350 var
01351 I: Integer;
01352 TableTypes: string;
01353 begin
01354 Result := ConstructVirtualResultSet(TableColumnsDynArray);
01355
01356 TableTypes := '';
01357 for I := 0 to Length(Types) - 1 do
01358 begin
01359 if TableTypes <> '' then
01360 TableTypes := TableTypes + ',';
01361 TableTypes := TableTypes + AnsiQuotedStr(Types[I], '''');
01362 end;
01363
01364 with GetStatement.ExecuteQuery(
01365 Format('exec sp_jdbc_tables %s, %s, %s, %s',
01366 [AQSNull(TableNamePattern), AQSNull(SchemaPattern), AQSNull(Catalog), AQSNull(TableTypes, '"')])) do
01367 begin
01368 while Next do
01369 begin
01370 Result.MoveToInsertRow;
01371 Result.UpdateStringByName('TABLE_CAT',
01372 GetStringByName('TABLE_CAT'));
01373 Result.UpdateStringByName('TABLE_SCHEM',
01374 GetStringByName('TABLE_SCHEM'));
01375 Result.UpdateStringByName('TABLE_NAME',
01376 GetStringByName('TABLE_NAME'));
01377 Result.UpdateStringByName('TABLE_TYPE',
01378 GetStringByName('TABLE_TYPE'));
01379 Result.UpdateStringByName('REMARKS',
01380 GetStringByName('REMARKS'));
01381 Result.InsertRow;
01382 end;
01383 Close;
01384 end;
01385 end;
01386
01387 {**
01388 Gets the schema names available in this database. The results
01389 are ordered by schema name.
01390
01391 <P>The schema column is:
01392 <OL>
01393 <LI><B>TABLE_SCHEM</B> String => schema name
01394 </OL>
01395
01396 @return <code>ResultSet</code> - each row has a single String column that is a
01397 schema name
01398 }
01399 function TZSybaseDatabaseMetadata.UncachedGetSchemas: IZResultSet;
01400 begin
01401 Result := ConstructVirtualResultSet(SchemaColumnsDynArray);
01402
01403 with GetStatement.ExecuteQuery('exec sp_jdbc_getschemas') do
01404 begin
01405 while Next do
01406 begin
01407 Result.MoveToInsertRow;
01408 Result.UpdateStringByName('TABLE_SCHEM',
01409 GetStringByName('TABLE_SCHEM'));
01410 Result.InsertRow;
01411 end;
01412 Close;
01413 end;
01414 end;
01415
01416 {**
01417 Gets the catalog names available in this database. The results
01418 are ordered by catalog name.
01419
01420 <P>The catalog column is:
01421 <OL>
01422 <LI><B>TABLE_CAT</B> String => catalog name
01423 </OL>
01424
01425 @return <code>ResultSet</code> - each row has a single String column that is a
01426 catalog name
01427 }
01428 function TZSybaseDatabaseMetadata.UncachedGetCatalogs: IZResultSet;
01429 begin
01430 Result := ConstructVirtualResultSet(CatalogColumnsDynArray);
01431
01432 with GetStatement.ExecuteQuery('exec sp_jdbc_getcatalogs') do
01433 begin
01434 while Next do
01435 begin
01436 Result.MoveToInsertRow;
01437 Result.UpdateStringByName('TABLE_CAT',
01438 GetStringByName('TABLE_CAT'));
01439 Result.InsertRow;
01440 end;
01441 Close;
01442 end;
01443 end;
01444
01445 {**
01446 Gets the table types available in this database. The results
01447 are ordered by table type.
01448
01449 <P>The table type is:
01450 <OL>
01451 <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
01452 "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
01453 "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
01454 </OL>
01455
01456 @return <code>ResultSet</code> - each row has a single String column that is a
01457 table type
01458 }
01459 function TZSybaseDatabaseMetadata.UncachedGetTableTypes: IZResultSet;
01460 const
01461 TableTypes: array[0..2] of string = ('SYSTEM TABLE', 'TABLE', 'VIEW');
01462 var
01463 I: Integer;
01464 begin
01465 Result := ConstructVirtualResultSet(TableTypeColumnsDynArray);
01466 for I := 0 to 2 do
01467 begin
01468 Result.MoveToInsertRow;
01469 Result.UpdateStringByName('TABLE_TYPE', TableTypes[I]);
01470 Result.InsertRow;
01471 end;
01472 end;
01473
01474 {**
01475 Gets a description of table columns available in
01476 the specified catalog.
01477
01478 <P>Only column descriptions matching the catalog, schema, table
01479 and column name criteria are returned. They are ordered by
01480 TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
01481
01482 <P>Each column description has the following columns:
01483 <OL>
01484 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
01485 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
01486 <LI><B>TABLE_NAME</B> String => table name
01487 <LI><B>COLUMN_NAME</B> String => column name
01488 <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
01489 <LI><B>TYPE_NAME</B> String => Data source dependent type name,
01490 for a UDT the type name is fully qualified
01491 <LI><B>COLUMN_SIZE</B> int => column size. For char or date
01492 types this is the maximum number of characters, for numeric or
01493 decimal types this is precision.
01494 <LI><B>BUFFER_LENGTH</B> is not used.
01495 <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
01496 <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
01497 <LI><B>NULLABLE</B> int => is NULL allowed?
01498 <UL>
01499 <LI> columnNoNulls - might not allow NULL values
01500 <LI> columnNullable - definitely allows NULL values
01501 <LI> columnNullableUnknown - nullability unknown
01502 </UL>
01503 <LI><B>REMARKS</B> String => comment describing column (may be null)
01504 <LI><B>COLUMN_DEF</B> String => default value (may be null)
01505 <LI><B>SQL_DATA_TYPE</B> int => unused
01506 <LI><B>SQL_DATETIME_SUB</B> int => unused
01507 <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
01508 maximum number of bytes in the column
01509 <LI><B>ORDINAL_POSITION</B> int => index of column in table
01510 (starting at 1)
01511 <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
01512 does not allow NULL values; "YES" means the column might
01513 allow NULL values. An empty string means nobody knows.
01514 </OL>
01515
01516 @param catalog a catalog name; "" retrieves those without a
01517 catalog; null means drop catalog name from the selection criteria
01518 @param schemaPattern a schema name pattern; "" retrieves those
01519 without a schema
01520 @param tableNamePattern a table name pattern
01521 @param columnNamePattern a column name pattern
01522 @return <code>ResultSet</code> - each row is a column description
01523 @see #getSearchStringEscape
01524 }
01525 function TZSybaseDatabaseMetadata.UncachedGetColumns(const Catalog: string;
01526 const SchemaPattern: string; const TableNamePattern: string;
01527 const ColumnNamePattern: string): IZResultSet;
01528 begin
01529 Result := ConstructVirtualResultSet(TableColColumnsDynArray);
01530
01531 with GetStatement.ExecuteQuery(
01532 Format('exec sp_jdbc_columns %s, %s, %s, %s',
01533 [AQSNull(TableNamePattern), AQSNull(SchemaPattern), AQSNull(Catalog), AQSNull(ColumnNamePattern)])) do
01534 begin
01535 while Next do
01536 begin
01537 Result.MoveToInsertRow;
01538 Result.UpdateStringByName('TABLE_CAT',
01539 ''{GetStringByName('TABLE_CAT')});
01540 Result.UpdateStringByName('TABLE_SCHEM',
01541 ''{GetStringByName('TABLE_SCHEM')});
01542 Result.UpdateStringByName('TABLE_NAME',
01543 GetStringByName('TABLE_NAME'));
01544 Result.UpdateStringByName('COLUMN_NAME',
01545 GetStringByName('COLUMN_NAME'));
01546 //The value in the resultset will be used
01547 // Result.UpdateShortByName('DATA_TYPE',
01548 // Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'))));
01549 Result.UpdateStringByName('TYPE_NAME',
01550 GetStringByName('TYPE_NAME'));
01551 Result.UpdateIntByName('COLUMN_SIZE',
01552 GetIntByName('COLUMN_SIZE'));
01553 Result.UpdateIntByName('BUFFER_LENGTH',
01554 GetIntByName('BUFFER_LENGTH'));
01555 Result.UpdateIntByName('DECIMAL_DIGITS',
01556 GetIntByName('DECIMAL_DIGITS'));
01557 Result.UpdateIntByName('NUM_PREC_RADIX',
01558 GetShortByName('NUM_PREC_RADIX'));
01559 Result.UpdateShortByName('NULLABLE',
01560 GetShortByName('NULLABLE'));
01561 Result.UpdateStringByName('REMARKS',
01562 GetStringByName('REMARKS'));
01563 Result.UpdateStringByName('COLUMN_DEF',
01564 GetStringByName('COLUMN_DEF'));
01565 Result.UpdateShortByName('SQL_DATA_TYPE',
01566 GetShortByName('SQL_DATA_TYPE'));
01567 Result.UpdateShortByName('SQL_DATETIME_SUB',
01568 GetShortByName('SQL_DATETIME_SUB'));
01569 Result.UpdateIntByName('CHAR_OCTET_LENGTH',
01570 GetIntByName('CHAR_OCTET_LENGTH'));
01571 Result.UpdateIntByName('ORDINAL_POSITION',
01572 GetIntByName('ORDINAL_POSITION'));
01573 Result.UpdateStringByName('IS_NULLABLE',
01574 GetStringByName('IS_NULLABLE'));
01575 Result.InsertRow;
01576 end;
01577 Close;
01578 end;
01579 Result.BeforeFirst;
01580 with GetStatement.ExecuteQuery(
01581 Format('select c.colid, c.name, c.type, c.prec, c.scale, c.status'
01582 + ' from syscolumns c inner join sysobjects o on (o.id = c.id)'
01583 + ' where o.name = %s order by colid', [AnsiQuotedStr(TableNamePattern, '''')])) do
01584 begin
01585 while Next do
01586 begin
01587 Result.Next;
01588 Result.UpdateBooleanByName('AUTO_INCREMENT',
01589 (GetShortByName('status') and $80) <> 0);
01590 Result.UpdateNullByName('CASE_SENSITIVE');
01591 Result.UpdateBooleanByName('SEARCHABLE',
01592 not (GetShortByName('type') in [34, 35]));
01593 Result.UpdateBooleanByName('WRITABLE',
01594 ((GetShortByName('status') and $80) = 0)
01595 and (GetShortByName('type') <> 37));
01596 Result.UpdateBooleanByName('DEFINITELYWRITABLE',
01597 Result.GetBooleanByName('WRITABLE'));
01598 Result.UpdateBooleanByName('READONLY',
01599 not Result.GetBooleanByName('WRITABLE'));
01600 if Result.GetBooleanByName('AUTO_INCREMENT') then
01601 begin
01602 Result.UpdateShortByName('NULLABLE', 1);
01603 Result.UpdateStringByName('IS_NULLABLE', 'YES');
01604 end;
01605 Result.UpdateRow;
01606 end;
01607 Close;
01608 end;
01609 end;
01610
01611 {**
01612 Gets a description of the access rights for a table's columns.
01613
01614 <P>Only privileges matching the column name criteria are
01615 returned. They are ordered by COLUMN_NAME and PRIVILEGE.
01616
01617 <P>Each privilige description has the following columns:
01618 <OL>
01619 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
01620 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
01621 <LI><B>TABLE_NAME</B> String => table name
01622 <LI><B>COLUMN_NAME</B> String => column name
01623 <LI><B>GRANTOR</B> => grantor of access (may be null)
01624 <LI><B>GRANTEE</B> String => grantee of access
01625 <LI><B>PRIVILEGE</B> String => name of access (SELECT,
01626 INSERT, UPDATE, REFRENCES, ...)
01627 <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
01628 to grant to others; "NO" if not; null if unknown
01629 </OL>
01630
01631 @param catalog a catalog name; "" retrieves those without a
01632 catalog; null means drop catalog name from the selection criteria
01633 @param schema a schema name; "" retrieves those without a schema
01634 @param table a table name
01635 @param columnNamePattern a column name pattern
01636 @return <code>ResultSet</code> - each row is a column privilege description
01637 @see #getSearchStringEscape
01638 }
01639 function TZSybaseDatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;
01640 const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;
01641 begin
01642 Result := ConstructVirtualResultSet(TableColPrivColumnsDynArray);
01643
01644 with GetStatement.ExecuteQuery(
01645 Format('exec sp_jdbc_getcolumnprivileges %s, %s, %s, %s',
01646 [AQSNull(Catalog), AQSNull(Schema), AQSNull(Table),
01647 AQSNullText(ColumnNamePattern, '''%''')])) do
01648 begin
01649 while Next do
01650 begin
01651 Result.MoveToInsertRow;
01652 Result.UpdateStringByName('TABLE_CAT',
01653 GetStringByName('TABLE_CAT'));
01654 Result.UpdateStringByName('TABLE_SCHEM',
01655 GetStringByName('TABLE_SCHEM'));
01656 Result.UpdateStringByName('TABLE_NAME',
01657 GetStringByName('TABLE_NAME'));
01658 Result.UpdateStringByName('COLUMN_NAME',
01659 GetStringByName('COLUMN_NAME'));
01660 Result.UpdateStringByName('GRANTOR',
01661 GetStringByName('GRANTOR'));
01662 Result.UpdateStringByName('GRANTEE',
01663 GetStringByName('GRANTEE'));
01664 Result.UpdateStringByName('PRIVILEGE',
01665 GetStringByName('PRIVILEGE'));
01666 Result.UpdateStringByName('IS_GRANTABLE',
01667 GetStringByName('IS_GRANTABLE'));
01668 Result.InsertRow;
01669 end;
01670 Close;
01671 end;
01672 end;
01673
01674 {**
01675 Gets a description of the access rights for each table available
01676 in a catalog. Note that a table privilege applies to one or
01677 more columns in the table. It would be wrong to assume that
01678 this priviledge applies to all columns (this may be true for
01679 some systems but is not true for all.)
01680
01681 <P>Only privileges matching the schema and table name
01682 criteria are returned. They are ordered by TABLE_SCHEM,
01683 TABLE_NAME, and PRIVILEGE.
01684
01685 <P>Each privilige description has the following columns:
01686 <OL>
01687 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
01688 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
01689 <LI><B>TABLE_NAME</B> String => table name
01690 <LI><B>GRANTOR</B> => grantor of access (may be null)
01691 <LI><B>GRANTEE</B> String => grantee of access
01692 <LI><B>PRIVILEGE</B> String => name of access (SELECT,
01693 INSERT, UPDATE, REFRENCES, ...)
01694 <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
01695 to grant to others; "NO" if not; null if unknown
01696 </OL>
01697
01698 @param catalog a catalog name; "" retrieves those without a
01699 catalog; null means drop catalog name from the selection criteria
01700 @param schemaPattern a schema name pattern; "" retrieves those
01701 without a schema
01702 @param tableNamePattern a table name pattern
01703 @return <code>ResultSet</code> - each row is a table privilege description
01704 @see #getSearchStringEscape
01705 }
01706 function TZSybaseDatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;
01707 const SchemaPattern: string; const TableNamePattern: string): IZResultSet;
01708 begin
01709 Result := ConstructVirtualResultSet(TablePrivColumnsDynArray);
01710
01711 with GetStatement.ExecuteQuery(
01712 Format('exec sp_jdbc_gettableprivileges %s, %s, %s',
01713 [AQSNull(Catalog), AQSNull(SchemaPattern), AQSNull(TableNamePattern)])) do
01714 begin
01715 while Next do
01716 begin
01717 Result.MoveToInsertRow;
01718 Result.UpdateStringByName('TABLE_CAT',
01719 GetStringByName('TABLE_CAT'));
01720 Result.UpdateStringByName('TABLE_SCHEM',
01721 GetStringByName('TABLE_SCHEM'));
01722 Result.UpdateStringByName('TABLE_NAME',
01723 GetStringByName('TABLE_NAME'));
01724 Result.UpdateStringByName('GRANTOR',
01725 GetStringByName('GRANTOR'));
01726 Result.UpdateStringByName('GRANTEE',
01727 GetStringByName('GRANTEE'));
01728 Result.UpdateStringByName('PRIVILEGE',
01729 GetStringByName('PRIVILEGE'));
01730 Result.UpdateStringByName('IS_GRANTABLE',
01731 GetStringByName('IS_GRANTABLE'));
01732 Result.InsertRow;
01733 end;
01734 Close;
01735 end;
01736 end;
01737
01738 {**
01739 Gets a description of a table's columns that are automatically
01740 updated when any value in a row is updated. They are
01741 unordered.
01742
01743 <P>Each column description has the following columns:
01744 <OL>
01745 <LI><B>SCOPE</B> short => is not used
01746 <LI><B>COLUMN_NAME</B> String => column name
01747 <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
01748 <LI><B>TYPE_NAME</B> String => Data source dependent type name
01749 <LI><B>COLUMN_SIZE</B> int => precision
01750 <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes
01751 <LI><B>DECIMAL_DIGITS</B> short => scale
01752 <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
01753 like an Oracle ROWID
01754 <UL>
01755 <LI> versionColumnUnknown - may or may not be pseudo column
01756 <LI> versionColumnNotPseudo - is NOT a pseudo column
01757 <LI> versionColumnPseudo - is a pseudo column
01758 </UL>
01759 </OL>
01760
01761 @param catalog a catalog name; "" retrieves those without a
01762 catalog; null means drop catalog name from the selection criteria
01763 @param schema a schema name; "" retrieves those without a schema
01764 @param table a table name
01765 @return <code>ResultSet</code> - each row is a column description
01766 @exception SQLException if a database access error occurs
01767 }
01768 function TZSybaseDatabaseMetadata.UncachedGetVersionColumns(const Catalog: string;
01769 const Schema: string; const Table: string): IZResultSet;
01770 begin
01771 Result := ConstructVirtualResultSet(TableColVerColumnsDynArray);
01772
01773 with GetStatement.ExecuteQuery(
01774 Format('exec sp_jdbc_getversioncolumns %s, %s, %s',
01775 [AQSNull(Catalog), AQSNull(Schema), AQSNull(Table)])) do
01776 begin
01777 while Next do
01778 begin
01779 Result.MoveToInsertRow;
01780 Result.UpdateShortByName('SCOPE',
01781 GetShortByName('SCOPE'));
01782 Result.UpdateStringByName('COLUMN_NAME',
01783 GetStringByName('COLUMN_NAME'));
01784 Result.UpdateShortByName('DATA_TYPE',
01785 Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'))));
01786 Result.UpdateStringByName('TYPE_NAME',
01787 GetStringByName('TYPE_NAME'));
01788 Result.UpdateIntByName('COLUMN_SIZE',
01789 GetIntByName('COLUMN_SIZE'));
01790 Result.UpdateIntByName('BUFFER_LENGTH',
01791 GetIntByName('BUFFER_LENGTH'));
01792 Result.UpdateIntByName('DECIMAL_DIGITS',
01793 GetIntByName('DECIMAL_DIGITS'));
01794 Result.UpdateShortByName('PSEUDO_COLUMN',
01795 GetShortByName('PSEUDO_COLUMN'));
01796 Result.InsertRow;
01797 end;
01798 Close;
01799 end;
01800 end;
01801
01802 {**
01803 Gets a description of a table's primary key columns. They
01804 are ordered by COLUMN_NAME.
01805
01806 <P>Each primary key column description has the following columns:
01807 <OL>
01808 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
01809 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
01810 <LI><B>TABLE_NAME</B> String => table name
01811 <LI><B>COLUMN_NAME</B> String => column name
01812 <LI><B>KEY_SEQ</B> short => sequence number within primary key
01813 <LI><B>PK_NAME</B> String => primary key name (may be null)
01814 </OL>
01815
01816 @param catalog a catalog name; "" retrieves those without a
01817 catalog; null means drop catalog name from the selection criteria
01818 @param schema a schema name; "" retrieves those
01819 without a schema
01820 @param table a table name
01821 @return <code>ResultSet</code> - each row is a primary key column description
01822 @exception SQLException if a database access error occurs
01823 }
01824 function TZSybaseDatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;
01825 const Schema: string; const Table: string): IZResultSet;
01826 begin
01827 Result := ConstructVirtualResultSet(PrimaryKeyColumnsDynArray);
01828
01829 with GetStatement.ExecuteQuery(
01830 Format('exec sp_jdbc_primarykey %s, %s, %s',
01831 [AQSNull(Catalog), AQSNull(Schema), AQSNull(Table)])) do
01832 begin
01833 while Next do
01834 begin
01835 Result.MoveToInsertRow;
01836 Result.UpdateStringByName('TABLE_CAT',
01837 GetStringByName('TABLE_CAT'));
01838 Result.UpdateStringByName('TABLE_SCHEM',
01839 GetStringByName('TABLE_SCHEM'));
01840 Result.UpdateStringByName('TABLE_NAME',
01841 GetStringByName('TABLE_NAME'));
01842 Result.UpdateStringByName('COLUMN_NAME',
01843 GetStringByName('COLUMN_NAME'));
01844 Result.UpdateShortByName('KEY_SEQ',
01845 GetShortByName('KEY_SEQ'));
01846 Result.UpdateStringByName('PK_NAME',
01847 GetStringByName('PK_NAME'));
01848 Result.InsertRow;
01849 end;
01850 Close;
01851 end;
01852 end;
01853
01854 {**
01855 Gets a description of the primary key columns that are
01856 referenced by a table's foreign key columns (the primary keys
01857 imported by a table). They are ordered by PKTABLE_CAT,
01858 PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
01859
01860 <P>Each primary key column description has the following columns:
01861 <OL>
01862 <LI><B>PKTABLE_CAT</B> String => primary key table catalog
01863 being imported (may be null)
01864 <LI><B>PKTABLE_SCHEM</B> String => primary key table schema
01865 being imported (may be null)
01866 <LI><B>PKTABLE_NAME</B> String => primary key table name
01867 being imported
01868 <LI><B>PKCOLUMN_NAME</B> String => primary key column name
01869 being imported
01870 <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
01871 <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
01872 <LI><B>FKTABLE_NAME</B> String => foreign key table name
01873 <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
01874 <LI><B>KEY_SEQ</B> short => sequence number within foreign key
01875 <LI><B>UPDATE_RULE</B> short => What happens to
01876 foreign key when primary is updated:
01877 <UL>
01878 <LI> importedNoAction - do not allow update of primary
01879 key if it has been imported
01880 <LI> importedKeyCascade - change imported key to agree
01881 with primary key update
01882 <LI> importedKeySetNull - change imported key to NULL if
01883 its primary key has been updated
01884 <LI> importedKeySetDefault - change imported key to default values
01885 if its primary key has been updated
01886 <LI> importedKeyRestrict - same as importedKeyNoAction
01887 (for ODBC 2.x compatibility)
01888 </UL>
01889 <LI><B>DELETE_RULE</B> short => What happens to
01890 the foreign key when primary is deleted.
01891 <UL>
01892 <LI> importedKeyNoAction - do not allow delete of primary
01893 key if it has been imported
01894 <LI> importedKeyCascade - delete rows that import a deleted key
01895 <LI> importedKeySetNull - change imported key to NULL if
01896 its primary key has been deleted
01897 <LI> importedKeyRestrict - same as importedKeyNoAction
01898 (for ODBC 2.x compatibility)
01899 <LI> importedKeySetDefault - change imported key to default if
01900 its primary key has been deleted
01901 </UL>
01902 <LI><B>FK_NAME</B> String => foreign key name (may be null)
01903 <LI><B>PK_NAME</B> String => primary key name (may be null)
01904 <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
01905 constraints be deferred until commit
01906 <UL>
01907 <LI> importedKeyInitiallyDeferred - see SQL92 for definition
01908 <LI> importedKeyInitiallyImmediate - see SQL92 for definition
01909 <LI> importedKeyNotDeferrable - see SQL92 for definition
01910 </UL>
01911 </OL>
01912
01913 @param catalog a catalog name; "" retrieves those without a
01914 catalog; null means drop catalog name from the selection criteria
01915 @param schema a schema name; "" retrieves those
01916 without a schema
01917 @param table a table name
01918 @return <code>ResultSet</code> - each row is a primary key column description
01919 @see #getExportedKeys
01920 }
01921 function TZSybaseDatabaseMetadata.UncachedGetImportedKeys(const Catalog: string;
01922 const Schema: string; const Table: string): IZResultSet;
01923 begin
01924 Result := ConstructVirtualResultSet(ImportedKeyColumnsDynArray);
01925
01926 with GetStatement.ExecuteQuery(
01927 Format('exec sp_jdbc_importkey %s, %s, %s',
01928 [AQSNull(Catalog), AQSNull(Schema), AQSNull(Table)])) do
01929 begin
01930 while Next do
01931 begin
01932 Result.MoveToInsertRow;
01933 Result.UpdateStringByName('PKTABLE_CAT',
01934 GetStringByName('PKTABLE_CAT'));
01935 Result.UpdateStringByName('PKTABLE_SCHEM',
01936 GetStringByName('PKTABLE_SCHEM'));
01937 Result.UpdateStringByName('PKTABLE_NAME',
01938 GetStringByName('PKTABLE_NAME'));
01939 Result.UpdateStringByName('PKCOLUMN_NAME',
01940 GetStringByName('PKCOLUMN_NAME'));
01941 Result.UpdateStringByName('FKTABLE_CAT',
01942 GetStringByName('FKTABLE_CAT'));
01943 Result.UpdateStringByName('FKTABLE_SCHEM',
01944 GetStringByName('FKTABLE_SCHEM'));
01945 Result.UpdateStringByName('FKTABLE_NAME',
01946 GetStringByName('FKTABLE_NAME'));
01947 Result.UpdateStringByName('FKCOLUMN_NAME',
01948 GetStringByName('FKCOLUMN_NAME'));
01949 Result.UpdateShortByName('KEY_SEQ',
01950 GetShortByName('KEY_SEQ'));
01951 Result.UpdateShortByName('UPDATE_RULE',
01952 GetShortByName('UPDATE_RULE'));
01953 Result.UpdateShortByName('DELETE_RULE',
01954 GetShortByName('DELETE_RULE'));
01955 Result.UpdateStringByName('FK_NAME',
01956 GetStringByName('FK_NAME'));
01957 Result.UpdateStringByName('PK_NAME',
01958 GetStringByName('PK_NAME'));
01959 Result.UpdateIntByName('DEFERRABILITY',
01960 GetIntByName('DEFERRABILITY'));
01961 Result.InsertRow;
01962 end;
01963 Close;
01964 end;
01965 end;
01966
01967 {**
01968 Gets a description of the foreign key columns that reference a
01969 table's primary key columns (the foreign keys exported by a
01970 table). They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
01971 FKTABLE_NAME, and KEY_SEQ.
01972
01973 <P>Each foreign key column description has the following columns:
01974 <OL>
01975 <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
01976 <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
01977 <LI><B>PKTABLE_NAME</B> String => primary key table name
01978 <LI><B>PKCOLUMN_NAME</B> String => primary key column name
01979 <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
01980 being exported (may be null)
01981 <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
01982 being exported (may be null)
01983 <LI><B>FKTABLE_NAME</B> String => foreign key table name
01984 being exported
01985 <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
01986 being exported
01987 <LI><B>KEY_SEQ</B> short => sequence number within foreign key
01988 <LI><B>UPDATE_RULE</B> short => What happens to
01989 foreign key when primary is updated:
01990 <UL>
01991 <LI> importedNoAction - do not allow update of primary
01992 key if it has been imported
01993 <LI> importedKeyCascade - change imported key to agree
01994 with primary key update
01995 <LI> importedKeySetNull - change imported key to NULL if
01996 its primary key has been updated
01997 <LI> importedKeySetDefault - change imported key to default values
01998 if its primary key has been updated
01999 <LI> importedKeyRestrict - same as importedKeyNoAction
02000 (for ODBC 2.x compatibility)
02001 </UL>
02002 <LI><B>DELETE_RULE</B> short => What happens to
02003 the foreign key when primary is deleted.
02004 <UL>
02005 <LI> importedKeyNoAction - do not allow delete of primary
02006 key if it has been imported
02007 <LI> importedKeyCascade - delete rows that import a deleted key
02008 <LI> importedKeySetNull - change imported key to NULL if
02009 its primary key has been deleted
02010 <LI> importedKeyRestrict - same as importedKeyNoAction
02011 (for ODBC 2.x compatibility)
02012 <LI> importedKeySetDefault - change imported key to default if
02013 its primary key has been deleted
02014 </UL>
02015 <LI><B>FK_NAME</B> String => foreign key name (may be null)
02016 <LI><B>PK_NAME</B> String => primary key name (may be null)
02017 <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
02018 constraints be deferred until commit
02019 <UL>
02020 <LI> importedKeyInitiallyDeferred - see SQL92 for definition
02021 <LI> importedKeyInitiallyImmediate - see SQL92 for definition
02022 <LI> importedKeyNotDeferrable - see SQL92 for definition
02023 </UL>
02024 </OL>
02025
02026 @param catalog a catalog name; "" retrieves those without a
02027 catalog; null means drop catalog name from the selection criteria
02028 @param schema a schema name; "" retrieves those
02029 without a schema
02030 @param table a table name
02031 @return <code>ResultSet</code> - each row is a foreign key column description
02032 @see #getImportedKeys
02033 }
02034 function TZSybaseDatabaseMetadata.UncachedGetExportedKeys(const Catalog: string;
02035 const Schema: string; const Table: string): IZResultSet;
02036 begin
02037 Result := ConstructVirtualResultSet(ExportedKeyColumnsDynArray);
02038
02039 with GetStatement.ExecuteQuery(
02040 Format('exec sp_jdbc_exportkey %s, %s, %s',
02041 [AQSNull(Catalog), AQSNull(Schema), AQSNull(Table)])) do
02042 begin
02043 while Next do
02044 begin
02045 Result.MoveToInsertRow;
02046 Result.UpdateStringByName('PKTABLE_CAT',
02047 GetStringByName('PKTABLE_CAT'));
02048 Result.UpdateStringByName('PKTABLE_SCHEM',
02049 GetStringByName('PKTABLE_SCHEM'));
02050 Result.UpdateStringByName('PKTABLE_NAME',
02051 GetStringByName('PKTABLE_NAME'));
02052 Result.UpdateStringByName('PKCOLUMN_NAME',
02053 GetStringByName('PKCOLUMN_NAME'));
02054 Result.UpdateStringByName('FKTABLE_CAT',
02055 GetStringByName('FKTABLE_CAT'));
02056 Result.UpdateStringByName('FKTABLE_SCHEM',
02057 GetStringByName('FKTABLE_SCHEM'));
02058 Result.UpdateStringByName('FKTABLE_NAME',
02059 GetStringByName('FKTABLE_NAME'));
02060 Result.UpdateStringByName('FKCOLUMN_NAME',
02061 GetStringByName('FKCOLUMN_NAME'));
02062 Result.UpdateShortByName('KEY_SEQ',
02063 GetShortByName('KEY_SEQ'));
02064 Result.UpdateShortByName('UPDATE_RULE',
02065 GetShortByName('UPDATE_RULE'));
02066 Result.UpdateShortByName('DELETE_RULE',
02067 GetShortByName('DELETE_RULE'));
02068 Result.UpdateStringByName('FK_NAME',
02069 GetStringByName('FK_NAME'));
02070 Result.UpdateStringByName('PK_NAME',
02071 GetStringByName('PK_NAME'));
02072 Result.UpdateIntByName('DEFERRABILITY',
02073 GetIntByName('DEFERRABILITY'));
02074 Result.InsertRow;
02075 end;
02076 Close;
02077 end;
02078 end;
02079
02080 {**
02081 Gets a description of the foreign key columns in the foreign key
02082 table that reference the primary key columns of the primary key
02083 table (describe how one table imports another's key.) This
02084 should normally return a single foreign key/primary key pair
02085 (most tables only import a foreign key from a table once.) They
02086 are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
02087 KEY_SEQ.
02088
02089 <P>Each foreign key column description has the following columns:
02090 <OL>
02091 <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
02092 <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
02093 <LI><B>PKTABLE_NAME</B> String => primary key table name
02094 <LI><B>PKCOLUMN_NAME</B> String => primary key column name
02095 <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
02096 being exported (may be null)
02097 <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
02098 being exported (may be null)
02099 <LI><B>FKTABLE_NAME</B> String => foreign key table name
02100 being exported
02101 <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
02102 being exported
02103 <LI><B>KEY_SEQ</B> short => sequence number within foreign key
02104 <LI><B>UPDATE_RULE</B> short => What happens to
02105 foreign key when primary is updated:
02106 <UL>
02107 <LI> importedNoAction - do not allow update of primary
02108 key if it has been imported
02109 <LI> importedKeyCascade - change imported key to agree
02110 with primary key update
02111 <LI> importedKeySetNull - change imported key to NULL if
02112 its primary key has been updated
02113 <LI> importedKeySetDefault - change imported key to default values
02114 if its primary key has been updated
02115 <LI> importedKeyRestrict - same as importedKeyNoAction
02116 (for ODBC 2.x compatibility)
02117 </UL>
02118 <LI><B>DELETE_RULE</B> short => What happens to
02119 the foreign key when primary is deleted.
02120 <UL>
02121 <LI> importedKeyNoAction - do not allow delete of primary
02122 key if it has been imported
02123 <LI> importedKeyCascade - delete rows that import a deleted key
02124 <LI> importedKeySetNull - change imported key to NULL if
02125 its primary key has been deleted
02126 <LI> importedKeyRestrict - same as importedKeyNoAction
02127 (for ODBC 2.x compatibility)
02128 <LI> importedKeySetDefault - change imported key to default if
02129 its primary key has been deleted
02130 </UL>
02131 <LI><B>FK_NAME</B> String => foreign key name (may be null)
02132 <LI><B>PK_NAME</B> String => primary key name (may be null)
02133 <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
02134 constraints be deferred until commit
02135 <UL>
02136 <LI> importedKeyInitiallyDeferred - see SQL92 for definition
02137 <LI> importedKeyInitiallyImmediate - see SQL92 for definition
02138 <LI> importedKeyNotDeferrable - see SQL92 for definition
02139 </UL>
02140 </OL>
02141
02142 @param primaryCatalog a catalog name; "" retrieves those without a
02143 catalog; null means drop catalog name from the selection criteria
02144 @param primarySchema a schema name; "" retrieves those
02145 without a schema
02146 @param primaryTable the table name that exports the key
02147 @param foreignCatalog a catalog name; "" retrieves those without a
02148 catalog; null means drop catalog name from the selection criteria
02149 @param foreignSchema a schema name; "" retrieves those
02150 without a schema
02151 @param foreignTable the table name that imports the key
02152 @return <code>ResultSet</code> - each row is a foreign key column description
02153 @see #getImportedKeys
02154 }
02155 function TZSybaseDatabaseMetadata.UncachedGetCrossReference(const PrimaryCatalog: string;
02156 const PrimarySchema: string; const PrimaryTable: string; const ForeignCatalog: string;
02157 const ForeignSchema: string; const ForeignTable: string): IZResultSet;
02158 begin
02159 Result := ConstructVirtualResultSet(CrossRefColumnsDynArray);
02160
02161 with GetStatement.ExecuteQuery(
02162 Format('exec sp_jdbc_getcrossreferences %s, %s, %s, %s, %s, %s',
02163 [AQSNull(PrimaryCatalog), AQSNull(PrimarySchema), AQSNull(PrimaryTable),
02164 AQSNull(ForeignCatalog), AQSNull(ForeignSchema), AQSNull(ForeignTable)])) do
02165 begin
02166 while Next do
02167 begin
02168 Result.MoveToInsertRow;
02169 Result.UpdateStringByName('PKTABLE_CAT',
02170 GetStringByName('PKTABLE_CAT'));
02171 Result.UpdateStringByName('PKTABLE_SCHEM',
02172 GetStringByName('PKTABLE_SCHEM'));
02173 Result.UpdateStringByName('PKTABLE_NAME',
02174 GetStringByName('PKTABLE_NAME'));
02175 Result.UpdateStringByName('PKCOLUMN_NAME',
02176 GetStringByName('PKCOLUMN_NAME'));
02177 Result.UpdateStringByName('FKTABLE_CAT',
02178 GetStringByName('FKTABLE_CAT'));
02179 Result.UpdateStringByName('FKTABLE_SCHEM',
02180 GetStringByName('FKTABLE_SCHEM'));
02181 Result.UpdateStringByName('FKTABLE_NAME',
02182 GetStringByName('FKTABLE_NAME'));
02183 Result.UpdateStringByName('FKCOLUMN_NAME',
02184 GetStringByName('FKCOLUMN_NAME'));
02185 Result.UpdateShortByName('KEY_SEQ',
02186 GetShortByName('KEY_SEQ'));
02187 Result.UpdateShortByName('UPDATE_RULE',
02188 GetShortByName('UPDATE_RULE'));
02189 Result.UpdateShortByName('DELETE_RULE',
02190 GetShortByName('DELETE_RULE'));
02191 Result.UpdateStringByName('FK_NAME',
02192 GetStringByName('FK_NAME'));
02193 Result.UpdateStringByName('PK_NAME',
02194 GetStringByName('PK_NAME'));
02195 Result.UpdateIntByName('DEFERRABILITY',
02196 GetIntByName('DEFERRABILITY'));
02197 Result.InsertRow;
02198 end;
02199 Close;
02200 end;
02201 end;
02202
02203 {**
02204 Gets a description of all the standard SQL types supported by
02205 this database. They are ordered by DATA_TYPE and then by how
02206 closely the data type maps to the corresponding JDBC SQL type.
02207
02208 <P>Each type description has the following columns:
02209 <OL>
02210 <LI><B>TYPE_NAME</B> String => Type name
02211 <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
02212 <LI><B>PRECISION</B> int => maximum precision
02213 <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
02214 (may be null)
02215 <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
02216 (may be null)
02217 <LI><B>CREATE_PARAMS</B> String => parameters used in creating
02218 the type (may be null)
02219 <LI><B>NULLABLE</B> short => can you use NULL for this type?
02220 <UL>
02221 <LI> typeNoNulls - does not allow NULL values
02222 <LI> typeNullable - allows NULL values
02223 <LI> typeNullableUnknown - nullability unknown
02224 </UL>
02225 <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
02226 <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
02227 <UL>
02228 <LI> typePredNone - No support
02229 <LI> typePredChar - Only supported with WHERE .. LIKE
02230 <LI> typePredBasic - Supported except for WHERE .. LIKE
02231 <LI> typeSearchable - Supported for all WHERE ..
02232 </UL>
02233 <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
02234 <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
02235 <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
02236 auto-increment value?
02237 <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
02238 (may be null)
02239 <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
02240 <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
02241 <LI><B>SQL_DATA_TYPE</B> int => unused
02242 <LI><B>SQL_DATETIME_SUB</B> int => unused
02243 <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
02244 </OL>
02245
02246 @return <code>ResultSet</code> - each row is an SQL type description
02247 }
02248 function TZSybaseDatabaseMetadata.UncachedGetTypeInfo: IZResultSet;
02249 begin
02250 Result := ConstructVirtualResultSet(TypeInfoColumnsDynArray);
02251
02252 with GetStatement.ExecuteQuery('exec sp_jdbc_datatype_info') do
02253 begin
02254 while Next do
02255 begin
02256 Result.MoveToInsertRow;
02257 Result.UpdateStringByName('TYPE_NAME',
02258 GetStringByName('TYPE_NAME'));
02259 Result.UpdateShortByName('DATA_TYPE',
02260 Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'))));
02261 Result.UpdateIntByName('PRECISION',
02262 GetIntByName('PRECISION'));
02263 Result.UpdateStringByName('LITERAL_PREFIX',
02264 GetStringByName('LITERAL_PREFIX'));
02265 Result.UpdateStringByName('LITERAL_SUFFIX',
02266 GetStringByName('LITERAL_SUFFIX'));
02267 Result.UpdateStringByName('CREATE_PARAMS',
02268 GetStringByName('CREATE_PARAMS'));
02269 Result.UpdateShortByName('NULLABLE',
02270 GetShortByName('NULLABLE'));
02271 Result.UpdateBooleanByName('CASE_SENSITIVE',
02272 GetShortByName('CASE_SENSITIVE') = 1);
02273 Result.UpdateShortByName('SEARCHABLE',
02274 GetShortByName('SEARCHABLE'));
02275 Result.UpdateBooleanByName('UNSIGNED_ATTRIBUTE',
02276 GetShortByName('UNSIGNED_ATTRIBUTE') = 1);
02277 Result.UpdateBooleanByName('FIXED_PREC_SCALE',
02278 GetShortByName('FIXED_PREC_SCALE') = 1);
02279 Result.UpdateBooleanByName('AUTO_INCREMENT',
02280 GetShortByName('AUTO_INCREMENT') = 1);
02281 Result.UpdateStringByName('LOCAL_TYPE_NAME',
02282 GetStringByName('LOCAL_TYPE_NAME'));
02283 Result.UpdateShortByName('MINIMUM_SCALE',
02284 GetShortByName('MINIMUM_SCALE'));
02285 Result.UpdateShortByName('MAXIMUM_SCALE',
02286 GetShortByName('MAXIMUM_SCALE'));
02287 Result.UpdateShortByName('SQL_DATA_TYPE',
02288 GetShortByName('SQL_DATA_TYPE'));
02289 Result.UpdateShortByName('SQL_DATETIME_SUB',
02290 GetShortByName('SQL_DATETIME_SUB'));
02291 Result.UpdateShortByName('NUM_PREC_RADIX',
02292 GetShortByName('NUM_PREC_RADIX'));
02293 Result.InsertRow;
02294 end;
02295 Close;
02296 end;
02297 end;
02298
02299 {**
02300 Gets a description of a table's indices and statistics. They are
02301 ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
02302
02303 <P>Each index column description has the following columns:
02304 <OL>
02305 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
02306 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
02307 <LI><B>TABLE_NAME</B> String => table name
02308 <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?
02309 false when TYPE is tableIndexStatistic
02310 <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);
02311 null when TYPE is tableIndexStatistic
02312 <LI><B>INDEX_NAME</B> String => index name; null when TYPE is
02313 tableIndexStatistic
02314 <LI><B>TYPE</B> short => index type:
02315 <UL>
02316 <LI> tableIndexStatistic - this identifies table statistics that are
02317 returned in conjuction with a table's index descriptions
02318 <LI> tableIndexClustered - this is a clustered index
02319 <LI> tableIndexHashed - this is a hashed index
02320 <LI> tableIndexOther - this is some other style of index
02321 </UL>
02322 <LI><B>ORDINAL_POSITION</B> short => column sequence number
02323 within index; zero when TYPE is tableIndexStatistic
02324 <LI><B>COLUMN_NAME</B> String => column name; null when TYPE is
02325 tableIndexStatistic
02326 <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending,
02327 "D" => descending, may be null if sort sequence is not supported;
02328 null when TYPE is tableIndexStatistic
02329 <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then
02330 this is the number of rows in the table; otherwise, it is the
02331 number of unique values in the index.
02332 <LI><B>PAGES</B> int => When TYPE is tableIndexStatisic then
02333 this is the number of pages used for the table, otherwise it
02334 is the number of pages used for the current index.
02335 <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
02336 (may be null)
02337 </OL>
02338
02339 @param catalog a catalog name; "" retrieves those without a
02340 catalog; null means drop catalog name from the selection criteria
02341 @param schema a schema name; "" retrieves those without a schema
02342 @param table a table name
02343 @param unique when true, return only indices for unique values;
02344 when false, return indices regardless of whether unique or not
02345 @param approximate when true, result is allowed to reflect approximate
02346 or out of data values; when false, results are requested to be
02347 accurate
02348 @return <code>ResultSet</code> - each row is an index column description
02349 }
02350 function TZSybaseDatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;
02351 const Schema: string; const Table: string; Unique: Boolean;
02352 Approximate: Boolean): IZResultSet;
02353 var
02354 Is_Unique, Accuracy: string;
02355 begin
02356 Result := ConstructVirtualResultSet(IndexInfoColumnsDynArray);
02357
02358 if Unique then
02359 Is_Unique := '''1'''
02360 else Is_Unique := '''0''';
02361 if Approximate then
02362 Accuracy := '''1'''
02363 else Accuracy := '''0''';
02364
02365 with GetStatement.ExecuteQuery(
02366 Format('exec sp_jdbc_getindexinfo %s, %s, %s, %s, %s',
02367 [AQSNull(Catalog), AQSNull(Schema), AQSNull(Table), Is_Unique, Accuracy])) do
02368 begin
02369 while Next do
02370 begin
02371 Result.MoveToInsertRow;
02372 Result.UpdateStringByName('TABLE_CAT',
02373 GetStringByName('TABLE_CAT'));
02374 Result.UpdateStringByName('TABLE_SCHEM',
02375 GetStringByName('TABLE_SCHEM'));
02376 Result.UpdateStringByName('TABLE_NAME',
02377 GetStringByName('TABLE_NAME'));
02378 Result.UpdateBooleanByName('NON_UNIQUE',
02379 GetShortByName('NON_UNIQUE') = 1);
02380 Result.UpdateStringByName('INDEX_QUALIFIER',
02381 GetStringByName('INDEX_QUALIFIER'));
02382 Result.UpdateStringByName('INDEX_NAME',
02383 GetStringByName('INDEX_NAME'));
02384 Result.UpdateShortByName('TYPE',
02385 GetShortByName('TYPE'));
02386 Result.UpdateShortByName('ORDINAL_POSITION',
02387 GetShortByName('ORDINAL_POSITION'));
02388 Result.UpdateStringByName('COLUMN_NAME',
02389 GetStringByName('COLUMN_NAME'));
02390 Result.UpdateStringByName('ASC_OR_DESC',
02391 GetStringByName('ASC_OR_DESC'));
02392 Result.UpdateIntByName('CARDINALITY',
02393 GetIntByName('CARDINALITY'));
02394 Result.UpdateIntByName('PAGES',
02395 GetIntByName('PAGES'));
02396 Result.UpdateStringByName('FILTER_CONDITION',
02397 GetStringByName('FILTER_CONDITION'));
02398 Result.InsertRow;
02399 end;
02400 Close;
02401 end;
02402 end;
02403
02404 {**
02405 Does the database support the given result set type?
02406 @param type defined in <code>java.sql.ResultSet</code>
02407 @return <code>true</code> if so; <code>false</code> otherwise
02408 }
02409 function TZSybaseDatabaseMetadata.SupportsResultSetType(
02410 _Type: TZResultSetType): Boolean;
02411 begin
02412 Result := True;
02413 end;
02414
02415 {**
02416 Does the database support the concurrency type in combination
02417 with the given result set type?
02418
02419 @param type defined in <code>java.sql.ResultSet</code>
02420 @param concurrency type defined in <code>java.sql.ResultSet</code>
02421 @return <code>true</code> if so; <code>false</code> otherwise
02422 }
02423 function TZSybaseDatabaseMetadata.SupportsResultSetConcurrency(
02424 _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;
02425 begin
02426 Result := True;
02427 end;
02428
02429 {**
02430
02431 Gets a description of the user-defined types defined in a particular
02432 schema. Schema-specific UDTs may have type JAVA_OBJECT, STRUCT,
02433 or DISTINCT.
02434
02435 <P>Only types matching the catalog, schema, type name and type
02436 criteria are returned. They are ordered by DATA_TYPE, TYPE_SCHEM
02437 and TYPE_NAME. The type name parameter may be a fully-qualified
02438 name. In this case, the catalog and schemaPattern parameters are
02439 ignored.
02440
02441 <P>Each type description has the following columns:
02442 <OL>
02443 <LI><B>TYPE_CAT</B> String => the type's catalog (may be null)
02444 <LI><B>TYPE_SCHEM</B> String => type's schema (may be null)
02445 <LI><B>TYPE_NAME</B> String => type name
02446 <LI><B>CLASS_NAME</B> String => Java class name
02447 <LI><B>DATA_TYPE</B> String => type value defined in java.sql.Types.
02448 One of JAVA_OBJECT, STRUCT, or DISTINCT
02449 <LI><B>REMARKS</B> String => explanatory comment on the type
02450 </OL>
02451
02452 <P><B>Note:</B> If the driver does not support UDTs, an empty
02453 result set is returned.
02454
02455 @param catalog a catalog name; "" retrieves those without a
02456 catalog; null means drop catalog name from the selection criteria
02457 @param schemaPattern a schema name pattern; "" retrieves those
02458 without a schema
02459 @param typeNamePattern a type name pattern; may be a fully-qualified name
02460 @param types a list of user-named types to include (JAVA_OBJECT,
02461 STRUCT, or DISTINCT); null returns all types
02462 @return <code>ResultSet</code> - each row is a type description
02463 }
02464 function TZSybaseDatabaseMetadata.UncachedGetUDTs(const Catalog: string;
02465 const SchemaPattern: string; const TypeNamePattern: string;
02466 const Types: TIntegerDynArray): IZResultSet;
02467 var
02468 I: Integer;
02469 UDTypes: string;
02470 begin
02471 Result := ConstructVirtualResultSet(UDTColumnsDynArray);
02472
02473 UDTypes := '';
02474 for I := 0 to Length(Types) - 1 do
02475 begin
02476 if Length(UDTypes) > 0 then
02477 UDTypes := UDTypes + ',';
02478 UDTypes := UDTypes + AnsiQuotedStr(IntToStr(Types[I]), '''');
02479 end;
02480
02481 with GetStatement.ExecuteQuery(
02482 Format('exec sp_jdbc_getudts %s, %s, %s, %s',
02483 [AQSNull(Catalog), AQSNullText(SchemaPattern, '''%'''),
02484 AQSNullText(TypeNamePattern, '''%'''), AQSNull(UDTypes, '"')])) do
02485 begin
02486 while Next do
02487 begin
02488 Result.MoveToInsertRow;
02489 Result.UpdateStringByName('TYPE_CAT',
02490 GetStringByName('TYPE_CAT'));
02491 Result.UpdateStringByName('TYPE_SCHEM',
02492 GetStringByName('TYPE_SCHEM'));
02493 Result.UpdateStringByName('TYPE_NAME',
02494 GetStringByName('TYPE_NAME'));
02495 Result.UpdateStringByName('JAVA_CLASS',
02496 GetStringByName('JAVA_CLASS'));
02497 Result.UpdateShortByName('DATA_TYPE',
02498 Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'))));
02499 Result.UpdateStringByName('REMARKS',
02500 GetStringByName('REMARKS'));
02501 Result.InsertRow;
02502 end;
02503 Close;
02504 end;
02505 end;
02506
02507 {**
02508 Create a statement for use
02509
02510 @return TZDBLibStatement
02511 }
02512 function TZSybaseDatabaseMetadata.GetStatement: IZSTatement;
02513 begin
02514 Result := GetConnection.CreateStatement;
02515 end;
02516
02517 end.
02518
02519