I found an apparent solution to the problem.
The
UncachedGetColumns method in
TZOracleDatabaseMetadata class in
ZDbcOracleMetadata unit uses the
ALL_TAB_COLUMNS VIEW in the
SYS SCHEMA.
According to a handbook for the Oracle DBA, VIEWS that start with "ALL_" "accessible by all users, giving all information of all objects accessible by a user. "
The VIEWS that start with USER_ "quelque are accessible by the user, providing information about its objects. "
I changed the SQL to query the
USER_TAB_COLUMNS VIEW. However, this VIEW does not have OWNER column. Therefore, some changes were needed in the SQL query and the call to
GetString was necessary to reduce the value of all indices smaller than 3:
Code: Select all
function TZOracleDatabaseMetadata.UncachedGetColumns(const Catalog: string;
const SchemaPattern: string; const TableNamePattern: string;
const ColumnNamePattern: string): IZResultSet;
var
SQL: string;
begin
Result := ConstructVirtualResultSet(TableColColumnsDynArray);
{
SQL := 'SELECT NULL, OWNER, TABLE_NAME, COLUMN_NAME, NULL, DATA_TYPE,'
+ ' DATA_LENGTH, NULL, DATA_PRECISION, DATA_SCALE, NULLABLE, NULL,'
+ ' DATA_DEFAULT, NULL, NULL, NULL, COLUMN_ID, NULLABLE'
+ ' FROM SYS.ALL_TAB_COLUMNS'
+ ' WHERE OWNER LIKE ''' + ToLikeString(SchemaPattern) + ''' AND TABLE_NAME LIKE '''
+ ToLikeString(TableNamePattern) + ''' AND COLUMN_NAME LIKE '''
+ ToLikeString(ColumnNamePattern) + '''';
}
{ Changed }
SQL := 'SELECT NULL, TABLE_NAME, COLUMN_NAME, NULL, DATA_TYPE,'
+ ' DATA_LENGTH, NULL, DATA_PRECISION, DATA_SCALE, NULLABLE, NULL,'
+ ' DATA_DEFAULT, NULL, NULL, NULL, COLUMN_ID, NULLABLE'
+ ' FROM SYS.USER_TAB_COLUMNS'
+ ' WHERE TABLE_NAME LIKE ''' + ToLikeString(TableNamePattern)
+ ''' AND COLUMN_NAME LIKE ''' + ToLikeString(ColumnNamePattern) + '''';
with GetConnection.CreateStatement.ExecuteQuery(SQL) do
begin
while Next do
begin
Result.MoveToInsertRow;
Result.UpdateNull(1);
// Result.UpdateString(2, GetString(2)); CHANGED
Result.UpdateString(3, GetString(2)); // Changed 3 to 2
Result.UpdateString(4, GetString(3)); // Changed 4 to 3
// Changed 6 to 5, 9 to 8, 10 to 9
Result.UpdateInt(5, Ord(ConvertOracleTypeToSQLType(
GetString(5), GetInt(8), GetInt(9))));
Result.UpdateString(6, GetString(5)); // Changed 6 to 5
Result.UpdateInt(7, GetInt(6)); // Changed 7 to 6
Result.UpdateNull(8);
Result.UpdateInt(9, GetInt(8)); // Changed 9 to 8
Result.UpdateInt(10, GetInt(9)); // Changed 10 to 9
if UpperCase(GetString(10)) = 'N' then
begin
Result.UpdateInt(11, Ord(ntNoNulls));
Result.UpdateString(18, 'NO');
end
else
begin
Result.UpdateInt(11, Ord(ntNullable));
Result.UpdateString(18, 'YES');
end;
Result.UpdateNull(12);
Result.UpdateString(13, GetString(12)); // Changed 13 to 12
Result.UpdateNull(14);
Result.UpdateNull(15);
Result.UpdateNull(16);
Result.UpdateInt(17, GetInt(16)); // Changed 17 to 16
Result.UpdateNull(19); //AUTO_INCREMENT
Result.UpdateBoolean(20, //CASE_SENSITIVE
GetIdentifierConvertor.IsCaseSensitive(GetString(3))); // Changed 4 to 3
Result.UpdateBoolean(21, True); //SEARCHABLE
Result.UpdateBoolean(22, True); //WRITABLE
Result.UpdateBoolean(23, True); //DEFINITELYWRITABLE
Result.UpdateBoolean(24, False); //READONLY
Result.InsertRow;
end;
Close;
end;
end;
Initial tests showed positive results. I'll continue testing and will communicate any new developments.
Tanks!
Josimar