Check the existance of a TABLENAME

Forum related to version 6.5.1 (alpha) and 6.6.x (beta) of ZeosLib's DBOs

Moderators: gto, cipto_kh, EgonHugeist

Post Reply
Bohse
Fresh Boarder
Fresh Boarder
Posts: 1
Joined: 19.01.2006, 23:53

Check the existance of a TABLENAME

Post by Bohse »

Environment:
firebird 1.5 with delphi 7

The Task:
Before creating a table check the database for a existance table with the same name.

used database:the example database 'EMPLOYEE' from firebird

First Try: use of
Zconnection.GetTableNames(<Pattern:String>,<Result:Stringlist>);

Pattern is one of a valid tabletype like 'TABLE','VIEW',....
Output: No Result

Second Try: use of ZSQLMetadata in conjunction with a Datasource
and a DBGrid:
Propertys:MetadataType = mdTables

Output: A Grid with all Tables marked as Table_Type 'VIEW'
and all System Tables marked as Table_Type 'SYSTEM TABLE'.

It would be a satisfying result but I found 'PHONE_LIST' marked as 'VIEW' twice.
If I use IBExpert(the personal Version) then I get Phone_LIST as 'VIEW' but not as 'TABLE'.

Who knows the answer or have a suggestion for my task??
barko
Senior Boarder
Senior Boarder
Posts: 51
Joined: 07.09.2005, 13:13

Post by barko »

I do this:

Code: Select all

try
  Table.Close;
  Table.SQL.text:='select * from mynewtable where id=:id';
  Table.ParamByName('id').AsString:='bla';
  Table.Open;
except // no table found... do create table...
  Table.Close;
  try
   Table.SQL.text:='create table mynewtable...';
   Table.ExecSQL;
   ...
  except end;
end;
Gerard
Fresh Boarder
Fresh Boarder
Posts: 12
Joined: 31.10.2005, 21:32

Post by Gerard »

I'm not quite sure if I've misunderstood what you have done with the ZConnection.GetTableName(). The 'Pattern' you pass is used to find matches on the table names. If you pass in an empty string you get a full list of tables.

If you need to find a single table eg. a table called 'employees', set the pattern to 'employees' and you will get a string list returned with one line in it if the table exists. If the table does not exist then you will get an empty string list. It isn't case sensitive so 'employees' and 'EMPLOYEES' return the same result.
zippo
Silver Boarder
Silver Boarder
Posts: 322
Joined: 12.10.2005, 18:01
Location: Slovenia

Post by zippo »

I prefer the totally SQL Way.. :)

Query1.SQL.Text := Show tables like "TABLENAME".
Query1.Open;
if Query1.Fields[0].AsString='' then
GoCreate TheTable

This works on every MySQL, but you coud use "if Query1.IsEmpty then..." or something like this.. :)

Advantage: Almost SQL Platform independant (it's SQL standard compliant), component independant (work with Zeos, sciBit,... etc.) Hope it helps.
btrewern
Expert Boarder
Expert Boarder
Posts: 193
Joined: 06.10.2005, 18:51

Post by btrewern »

I'm not sure if it is SQL spec complient but I shouldn't rely on it as I don't think it works on PostgreSQL, MS SQL Server, DB2 or Oracle.

Ben
DavidVTaylor
Zeos Dev Team
Zeos Dev Team
Posts: 13
Joined: 04.02.2006, 05:34
Location: Virginia
Contact:

Post by DavidVTaylor »

IMPORTANT NOTE:

If you are using GetTableNames with the IB/FB protocol (maybe others) there is a subtle but important bug (feature?) that may bite you. The Pattern passed to the GetTableNames method treats "_" and "%" as wildcard characters. The choice of these particular characters appears to be because these are also wildcard characters in a SQL LIKE expression. Internally LIKE expressions are used to handle wildcard Patterns.

This is important because it will cause unexpected results when a table name such as "PHONE_LIST" is passed as the pattern. Often you will see multiple matches in the results for what should have been an exact match. This may account for the problems Bohse encountered.

Unfortunately, there is currently no way to escape these characters to make the method treat them as literal. There appears to be a mechanism built into Zeos for this purpose, but it is currently broken, at least for IB/FB protocol. Not sure if this problem exists for other meta data methods or protocols.

BTW - This problem was discovered because it caused strange Evolve problems when using Zeos with InstantObjects. A work around was added to the InstantObjects Zeos broker until this gets fixed properly.

David
zippo
Silver Boarder
Silver Boarder
Posts: 322
Joined: 12.10.2005, 18:01
Location: Slovenia

Post by zippo »

DavidVTaylor
Zeos Dev Team
Zeos Dev Team
Posts: 13
Joined: 04.02.2006, 05:34
Location: Virginia
Contact:

Post by DavidVTaylor »

Yep, the comments on querying system tables are right in target. This is how Zeos implements GetTableNames. The problem is that the wildcard expressions supported by the LIKE comparison operator conflict with legal table names. This is how the issue came to light, I normally uppercase my table names and separate words with underscores (e.g. "USER_ROLES"). Problem is the underscore is also a wildcard.

I have some ideas on how to fix this issue. Just waiting to see if I can get added to the developer list. I understand the project is in a state of flux.

David
ChaosBiker
Fresh Boarder
Fresh Boarder
Posts: 22
Joined: 26.08.2008, 12:36

Post by ChaosBiker »

Is ti just me,

or does GetTableNames ignore the Database property? and just lists ALL ?
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post by mdaems »

Chaosbiker, what database are you using?
Have a look at the TZConnection.GetTableNames procedure and the TZXXXXXXXDatabaseMetadata.UncachedGetTables function (replace XXXX by your server). Normally the database isn't a parameter as default usage of a connection makes you connect to one specific db. Unless you are using dbless=true (which for mysql makes a connection to the full server with no database activated). So the metadata should in come from one database only. When using multiple schema's in a database (eg. postgres) probably all tables are shown in all schema's unless you add a schema pattern in your GetTableNames call.

Mark
Image
ChaosBiker
Fresh Boarder
Fresh Boarder
Posts: 22
Joined: 26.08.2008, 12:36

Post by ChaosBiker »

nvm,
solved by using an sql query instead

was just wanting to abuse ZConnecting gettablenames as a quick and dirty resolution

but it seems to list all tables from all db's..

not jsut the tables from a single db
Post Reply