dbitable - an object-oriented Perl module for handling single tables from an SQL database.
use dbitable;
my $tab= dbitable->new('table', $database_handle,
$table_name, $primary_key)->load();
$tab->value($key1,$column_name,$new_value);
$tab->store();
$tab->pretty_print();
This module defines the dbitable - class. A dbitable-object can hold some or all parts of a table of an SQL database. It is also possible, to load the results of a user-defined view into a dbitable-object. And a dbitable-object can also be used to read or write to an ASCII file in a (more or less) human-readable format.
dbitable is based on the DBI module, see also the DBI manpage for more information.
Two basic methods for a table are load
and store
. These methods are used to load data from the database or store data to the database or the file.
The usual way of handling a dbitable-object is to create it, fetch some data with load
, inspect or modify the data, and, optionally, write the table back to the database using store
.
To do all this, the user of this module doesn't need to know the SQL language. Knowledge on the basics of relational databases, however, will be needed.
In order to access the database and create a database-handle, the following two functions can be used:
my $dbh= dbitable::connect_database($dbname,$username,$password)
This method creates a connection to the database. The database corresponds to the first parameter of the connect
function of the DBI module. See also the DBI manpage. The function returns the DBI-handle or undef
in case of an error. The DBI-handle is also stored in the internal global handle variable. This variable is used as default in the dbitable constructor function new()
when it's DBI-handle parameter is an empty string ("") or undef
.
dbitable::disconnect_database($dbi_handle)
This function is used to disconnect from the database. If the parameter $dbi_handle
is an empty string, the default DBI-handle is used (see also description of connect_database
).
A dbitable object is created using the new
method:
my $tab= dbitable->new('table',$database_handle,
$table_name, $primary_key);
my $tab= dbitable->new('view',$database_handle,
$table_name, $primary_key, $sql_query);
my $tab= dbitable->new('file',$filename,$tag);
my $tab= dbitable->new('file',$filename,$tag,@column_list);
# clone the existing structure:
my $tab2= $tab->new();
my $tab2= $tab->new('table',$database_handle,
$table_name, $primary_key);
my $tab2= $tab->new('view',$database_handle,
$table_name, $primary_key, $sql_query);
my $tab2= $tab->new('file',$filename,$tag);
The new
method currently knows three parameter formats. Note that, if new is called as method of a parent dbitable-object, the parent object is cloned and the type (table,view or file) is changed to the type specified in the first parameter.
The $database_handle
parameter may be a valid database-handle, e.g. created with the connect_database
function, or an empty string. In this case, the default database-handle is used (see description of connect_database
).
Notes on the primary key:
The primary key is a single column or a combination of columns that is unique for each line in a table and gives a means to access single lines of the table. However, dbitable also supports tables, where such a column with unique values doesn't exist. In this case, dbitable just assigns a number to all lines in the table, starting with "1".
The primary key is set or found in the following way:
In this case, the user supplies the information, which column is to use as primary key. The $primary_key
parameter in the examples above is a string with the name of that column. Note that this column must have a value that is unique for each line. Otherwise several lines will occupy the same space in the dbitable-object which means that some lines in the dbitable-object will be missing.
In this case, the user supplies the information, which columns are to use as primary key. The $primary_key
parameter is in this case a reference to an array of column names. The primary key is then composed by the value of all the columns concatenated with the character seqeuence "||". Example:
my $tab= dbitable->new('table',$database_handle,
$table_name,
[$primary_key1_column1,
$primary_key1_column2 ...]
);
If you give "" (the empty string) or <undef> as value for the $primary_key
parameter, dbitable tries to find out the primary key columns itself by querying the database. In many cases, dbitable will determine the correct primary key columns, which are then used to identify each single line of the table. If dbitable is not able to find the primary key columns, it will use line-numbering (see below) to access the lines of the table.
For tables of the type "view" when the user didn't specify the primary key columns like shown above or for tables of the type "table" where the user didn't specify and dbitable couldn't find the primary key columns by another database query, the lines of the table are simply numbered. Each line of the table is accessed with a number, starting with "1" for the first line. There are no primary key columns in this case. Note that functions like primary_keys()
return undef
for such an object.
The three object types
"table"
With "table" the dbi-table object will hold a some or all parts of a single table. The name of the table is given with the $table_name
parameter, the name of the primary key is given with the $primary_key
parameter (see the section above on primary keys). Note that dbitable will not work correctly, if the primary key is not unique for each line of the table. Note too, that usually the primary key is a numeric (integer) field in the table.
"view"
With "view", the dbi-table object will hold the result of an arbitrary SQL-query. Note that in this query, each column must be named with a unique name. This means that for columns that are calculated or assembled, they must be given a unique name with the "AS" SQL-statement. Of course, a dbitable object, that was created as "view" cannot be written back to the database, so store
will return an error. The table-name parameter has in this case no special meaning. The name of the primary key is given with the $primary_key
parameter (see the section above on primary keys).
"file"
With "file", the load
and store
functions on this object will will not connect to the database, but work on an ASCII file instead. A single ASCII file can hold several dbitable-objects, they are distinguished in the file by their "tag", basically a unique string that identifies them. With store
, if there is already a section with the tag $tag
in the file, it will simply be overwritten.
If the $filename
parameter is a reference to a scalar variable, this scalar variable will be used instead of a file. load() will then read from the contents of that variable and store() will write to that variable.
If the $filename
parameter is an empty string, standard-in and standard-out will be used to when load() or store() is called on this table.
Note that as an option, a list (@column_list
) can be specified for a table-object that is created as an empty object with no data. The @column_list
has to be a list consisting of the name of the primary key, and a list of the names of all columns.
This is not needed, if the table is loaded later (see load
) from a file, since the file already contains a list of all columns and the name of the primary key.
$table->load()
$table->load(%options)
my $tab= dbitable->new($database_handle,
'table',$table_name, $primary_key)->load();
This method loads the table from the database (for the type "table") or from a file (type "file") or via a user-defined SQL statement (type "view"). %options
is a hash that is used to pass optionial parameters to the function. The function returns the object itself, so it can be cascaded with new
in a single call, as you can see in the third example.
In case of an error, the function calls dbdrv::dberror
or dbdrv::dbwarn
and returns undef
. If the dbitable-object already contains data and the SQL command issued fails, the data will be left intact.
Known options are:
"filter"
A filter can only be used for the type "table". It is a way to specify that only a part of the table shall be fetched. A typical call of the load
function with a filter is:
$table->load(filter=> ["equal",$column_name,$column_value])
As you can see, filter is a hash-key that has as a value a list-reference. The list consists of at least one element, the filter-type. This is possibly followed by a list of filter-parameters.
known filters:
$table->load(filter=> ["equal",$column_name,$column_value])
In this case, only lines of the table, where column $column_name
has a value that equals $column_value
are fetched.
$table->load(filter=> ["SQL",$sql_statement])
This is used to specify the "WHERE" part of the SQL "SELECT" statement directly. Note that $sql_statement
must not contain the word "WHERE" itself, dbitable adds this automatically.
"primary_key"
$table->load(primary_key=>"preserve")
This option can only be used for the type "file" and defines the primary_key mode. It must be either "preserve" or "generate". With "preserve", the column that is the primary key is simply taken from the file as it is. "preserve" is the default, if the primary_key mode is not specified.
With "generate" however, when the primary key is zero (0), a new (for that table-line unique-) primary key is generated. This is useful, when many lines are added to the file with a simple text editor. In this case, the primary key field is set to zero. When the file is loaded with the load
method, a new unique primary key is created while loading the file. Otherwise, the user would have to count lines, and create unique numbers for each new line he adds, which would be a rather dull task... ;)
Note that "generate" is not allowed for tables, where only a combination of several columns forms the primary key.
"save_native_order"
$table->load(save_native_order=>1)
This option can only be used for the type "table" or "view". In this case the order of the table-lines as they come from the database request is stored. This order of primary keys can later be requested by calling primary_keys()
with the option "order_native".
"order_by"
$table->load(order_by=> $sql_command)
This is used to specify the "ORDER BY" part of the SQL "SELECT" statement directly. Note that $sql_statement
must not contain the words "ORDER BY" itself, dbitable adds this automatically. This option implies the option "save_native_order" (see above).
"mode"
$table->load(mode=>'overwrite')
This option can only be used for the type 'table'. It defines what to do, if the table already contains data before load()
is executed. Three modes are known:
This is the default. With "set", all lines from the table are removed, before new lines are loaded from the database.
With "add", the lines from the database are added to the
lines already in the table. Lines that were not loaded from the
database are marked "inserted". Lines that found in the table
already but are different from that in the database are marked
"updated".
"overwrite" is similar to "add', but in this case lines that are found already in the table but also in the database are overwritten with the values from the database. The internal marking of lines as "inserted" or "updated" has a meaning when a store()
is executed for that table-object later.
"pretty"
$table->load(pretty=>1)
This option can only be used for the type "file". "pretty" must be either "0" or "1". With "0", the file is just read as it is, this is the default, when "pretty" is not defined. With "1", spaces at the end of fields are removed. This option is needed, when the file was created (via store
) with the "pretty" option also active (see store
).
"no_aliases"
$table->load(no_aliases=>1)
This option can only be used for the type "file". "no_aliases" must be either "0" or "1". With "0", the [Aliases] section from the file is not read.
"new_name"
$table->load(new_name=>"my_new_table_name")
By this option, the internal table name is changed to the new given name. This may be useful when a table is loaded and shall then be stored under a different name.
$table->store()
$table->store(%options)
This method writes the content of the table back to the database (for type "table") or to the file (for type "file").
Known options are:
"primary_key"
$table->store(primary_key=>"preserve")
This option can only be used for the type "table" and defines the primary_key mode. This is only relevant for lines that were added to the table and that are not yet in the database (store
uses the SQL command "INSERT" in this case).
The primary-key mode must be either "preserve" or "generate", "generate" is the default, when this option is not specified.
With "generate" , the primary key is calculated as a small unique number for each new line in the table (note that it must be ensured that each line in the table has a unique primary key). Before store
, each added line in the table has a preliminary primary key (a rather large number). During store, the value of the primary key changes, the old, preliminary one however, remains valid as an alias (see add_aliases
).
With "preserve", the value of the primary key in the table is just taken as it is. The user must ensure, that this key is unique for the new inserted lines in the table-object. This mode is only useful, when the primary key was directly set by the user.
Note that "generate" is not allowed for tables where only a combination of columns forms the primary key.
"pretty"
$table->store(pretty=>1)
This option can only be used for the type "file". "pretty" must be either "0" or "1". With "0", the file is written in a space-saving format. With "1", spaces are added at the end of fields, to make the file more look like a real table. Files that were written with the "pretty" option enabled, should only be read (via load
) with the "pretty" option also enabled.
"no_aliases"
$table->store(no_aliases=>1)
This option can only be used for the type "file". "no_aliases" must be either "0" or "1". With "0", the file is written with aliases, keys that reference single lines of the table. With "1" this section is omitted.
"order_by"
$table->store(order_by=>[$column_name1,$column_name2])
This option can only be used for the type "file". It defines, wether lines should be sorted by certain colums. The value may be the name of a single column or (as shown above) a reference to a list of column names.
"col_maps"
$table->store(col_maps=>{ $column1 => \%col_map1,
$column2 => \%col_map2, ... } )
By this option, column-maps can be specified. These map the values of a column to another value. Currently these are only used for sorting (see above).
$table->export_csv($filename, %options)
This method exports to a table to a file using the csv format, which means comma separated value. If $filename
is an empty string or <undef>, the table is written to standard-out. The following options are known:
"order_by"
$table->export_csv($filename,
order_by=>[$column_name1,$column_name2])
This option can only be used for the type "file". It defines, wether lines should be sorted by certain colums. The value may be the name of a single column or (as shown above) a reference to a list of column names.
"col_maps"
$table->export_csv($filename,
col_maps=>{ $column1 => \%col_map1,
$column2 => \%col_map2, ... } )
By this option, column-maps can be specified. These map the values of a column to another value. Currently these are only used for sorting (see above).
"col_selection"
$table->export_csv($filename, col_selection=> \@colum_names)
This exports only the columns of a table that are listed in @colum_names
"pk_selection"
$table->export_csv($filename, pk_selection=> \@pk_selection)
This exports only lines of the table whose primary key are listed in the given array @pk_selection
.
$table->import_csv($filename, %options)
This method imports a table from a file using the csv format.
$dest_tab->import_table($source_tab,%options);
This method is used to import the contents of an existing table-object into a new one. It is not necessary, that both tables are of the same type. Known options are:
"mode"
$dest_tab->import_table($source_tab, mode=>"set_lines");
This is the import mode. Two modes are known, "add_lines" and "set_lines", "add_lines" is the default. With "add_lines", the lines of the source-tables are added to the lines that already exist in the destination table. With "set_lines" however, the destination table is made equal to the source-table. All lines that are not present in the source-table (as defined by the primary-key) are deleted.
"primary_key"
$dest_tab->import_table($source_tab, primary_key=>"generate");
This option defines the primary_key mode. It must be either "preserve" or "generate", "generate" is the default.
It is only relevant for lines that were added to the table.
With "generate" , the primary key is calculated as a large unique number for each new line in the table, called preliminary key. If the table is written to the database (see "store"), this key is replaced with a small unique number, the old one, however, remains valid as an alias (see add_aliases
).
With "preserve", the value of the primary key is just taken from the source-table and remains unchanged. If the table-object is written to the database (see store
), the user must ensure, that this key is unique for new inserted lines.
Note that "generate" is not allowed for tables, where only a combination of several columns forms the primary key.
"column_aliases"
$dest_tab->import_table($source_tab,
column_aliases=>
{ $dest_col1 => $src_col1,
$dest_col2 => $src_col2 });
column-aliases are used to map colums of the source-table to columns of the destination-table that have a different name. Note that for columns, where a column-alias is not defined, columns of the source are just mapped to columns of the destination that have the same name.
my $dbh= dbitable::std_database_handle();
This returns the internal standard database-handle. This database-handle is used, when the undef
or an empty string is used where otherwise a database-handle is expected. The standard database-handle is simply the last database-handle that was returned by the function dbitable::connect_database
. If dbitable::connect_database
was never called, std_database_handle
returns undef
.
my @keys= $table->primary_keys(%options)
This method returns a list consisting of the primary key of each line of the table. If no options are given, all the primary keys are given in a more or less random order.
The following options are known:
my @keys= $table->primary_keys(order_native=>1)
returns the primary keys just in the order they were returned from the database. Note that this only works when each load
command on the dbitable object had the option "save_native_order" set.
my @keys= $table->primary_keys(order_by=>[@column_names_list])
the primary keys are sorted according to the contents of the columns given in the list. The first column has the highest precedence. When the 1st column is equal in two lines, then the second column is used for further sorting and so on.
my @keys= $table->primary_keys(col_maps=>{ $column1 => \%col_map1,
$column2 => \%col_map2, ... } )
By this option, column-maps can be specified. These map the values of a column to another value. Currently these are only used for sorting (see above).
my @keys= $table->primary_keys(filter=>'updated')
my @keys= $table->primary_keys(filter=>'inserted')
In this case, only primary keys of lines are returned, that are marked as "updated" or marked as "inserted".
my @pk_cols= $table->primary_key_columns()
This method returns the names of the primary-key columns in upper case. In most cases there is exactly one primary key column. Note that a table may also have no primary key columns at all (see comments on primary keys at the start of this document). The function returns undef
in this case.
my @pk_col_indices= $table->primary_key_column_indices()
This method returns the indices of the primary-keys in the list of all columns. The index numbering of all columns starts with 0
. Note that a table may also have no primary key columns at all (see comments on primary keys at the start of this document). The function returns undef
in this case.
if ($table->primary_keys_are_numeric())
{ ... }
This function returns 1 when all primary key columns are numbers. When there is only one primary key column and it is numeric, the primary key generation feature (primary key mode: "generate") can be used.
if ($table->primary_key_auto_generate_possible())
{ ... }
This function returns 1 when it is with the current table possible to use auto-generated primary keys (see above).
my @columns= $table->column_list()
This method returns a list consisting of all column names in upper case. The columns have the same sort order as in the oracle database.
my %columns= $table->column_hash()
This method returns a hash that maps each column-name it's column-index. Columns are numbered starting with 0.
my %columns= $table->column_properties()
my $length= $table->column_properties($columnname, $propertyname)
This method returns a hash that maps each column-name it's type, length, precision, null-flag and default value if no columnname and one of the property names given as argument. If columnname and propertyname given the value will be returned.
my $type= get_column_type($columnname)
This method returns the kind of logical columntype for $columnname. (string, number, date, file or <undef>)
my $object = get_object_type()
If you want to know what there is received from database (table, view or sql (query)), use this simple function.
my %columns= $table->max_column_widths($minwidth,$maxwidth)
This method returns a list that contains the maxmimum width for each column. It is guaranteed that the returned values are larger than $minwidth
and smaller than $maxwidth
.
my $r_foreign_keys= $table->foreign_keys()
This method returns a reference to a hash that maps column-names to a list containing two elements, the name of the foreign table and the column-name in the foreign table. Note that this function works only for the type 'table'.
my $r_resident_keys= $table->resident_keys()
This method returns a reference to a hash that maps column-names to a list of lists. Each sub-list contains two elements, the name of the resident table and the column-name in the resident table. "Resident" is used here in opposition to "foreign". Viewed from the perspective of the resident table, the current table is the foreign table. The same relation is between foreign key and resident key. A foreign key is always unique, it belongs to a single foreign table. Viewed from the other side, this uniqueness is not guaranteed. That is the reason that the hash contains a list of lists. Note that this function works only for the type 'table'.
my $value= $table->value($primary_key, $column_name)
$table->value($primary_key, $column_name, $value)
This method is used to get or set a value, that means a single field of a single line. In the first form, the value is returned, in the 2nd form, the value is set. Note that changes do only take effect in the database or file, when store()
is called later on. Note too, that in the 2nd form, the function returns $value
when everything was ok, and undef
if setting the value was impossible due to constraints dbitable.pm knows of (e.g. primary keys must be always unique in the table).
my @pk_list= $table->find($column_name, $value, %flags)
This method searches the table to find a row where the value in the specified column matches the given value. Note that this method may be slow (a linear search) for columns that are not the primary key column. The method returns a list of primary keys that fullfill the match criteria. The %flags
parameter is used to pass certain options. Known options are:
If this is set (non-zero) the find function returns only the primary key of the first line that matches, nothing more.
If this is set (non-zero) the function warns when the given column us not the primary-key column.
If this is set (non-zero) the function warns when more than one line was found that matches the given value.
my $primary_key= $table->add_line(%values)
This method is used add a line to the table. %values
is a hash, that contains "column-name" "value" -pairs for the line. Note that each column must be specified and column-names must be upper-case! Currently there are no defaults supported. Note that the method returns the primary key for the new line. Note too, that this primary key changes with the next call of store()
, see also store()
, but via aliasing (see add_aliases
) it can then still be used to access the line. If the value of the primary key is specified in the list of values, it is taken as it is, and no new primary key is generated.
$table->delete_line($primary_key)
This method deletes a line from the table. Note that this change is made in the database or file only at the next call of store()
.
$table->add_column_aliases($column_name,%options)
This method is used to add aliases for a specific column to the column-aliases. Two options are known, "uppercase" and "lowercase". The alias is forced to be upper- or lowercase if one of these options is set.
$table->add_aliases(%aliases)
This method is used to add aliases to the table. An alias is a key that is different from the value of the primary key, that can be used to access a single line. An arbitrary number of aliases can be defined for a line. Note however, that each alias must be unique. The %aliases
parameter is a hash, containing pairs of the alias and the corresponding primary key.
my $primary_key= $table->resolve_alias($alias)
This method returns the primary key that is associated with a given alias.
my $max= $table->max_key()
This function returns the maximum primary key for a given table. Note that this value is obtained directly by an SQL query from the database, no matter what the current content of the table-object is.
$table->dump()
This method dumps the complete internal data-structure of a table-object and is for debugging purposes only.
my $r_buffer= $table->dump_s()
This method dumps the complete internal data-structure of a table-object to a text variable and returns a reference to that variable. It is for debugging purposes only.
$table->pretty_print()
$table->pretty_print(%options)
This method is used to pretty-print a given table.
Known options are:
"order_by"
$table->pretty_print(order_by=>[$column_name1,$column_name2])
This option defines, wether lines should be sorted by certain colums. The value may be the name of a single column or (as shown above) a reference to a list of column names.
"col_maps"
$table->pretty_print(col_maps=>{ $column1 => \%col_map1,
$column2 => \%col_map2, ... } )
By this option, column-maps can be specified. These map the values of a column to another value. Currently these are only used for sorting (see above).
when set to 1, the deletion of lines in the table is only simulated and not done for real. The default of this variable is 1, so deleting lines is disabled as default !
This variable contains the error-message for the last error non-fatal that occured. An example is the case, when a new object of type "table" is created, but the table doesn't exist. new()
returns undef
in this case and $last_error
is set to "table doesn't exist".
This example queries the p_insertion table here at HZB. It connects to the database and creates a "table" object. new
and load
are called in one line:
use strict;
use dbitable;
my $dbname= "DBI:Oracle:bii_par";
my $user="guest";
my $pass="bessyguest";
dbitable::connect_database($dbname,$user,$pass) or die;
my $tab= dbitable->new('table',"",'p_insertion',
'insertion_key')->load();
$tab->pretty_print();
dbitable::disconnect_database();
In this example, the insertion-device name-key (a number) is mapped to the insertion-device name. For this, the "view" type is used. The device-name has to be constructed (a simple string concatenation) by querying 5 tables. Note that the "constructed" column consists of a concatenation of "part_name", "part_index", "part_family", "part_subdomain", "part_postfix" and "part_domain" and is named (naming is imperative!) to "device_name" by the "... AS device_name" part of the statement. The resulting table-object is just like any other table object, except that a call of the store() method is not allowed.
use strict;
use dbitable;
my $dbname= "DBI:Oracle:bii_par";
my $user="guest";
my $pass="bessyguest";
dbitable::connect_database($dbname,$user,$pass) or die;
my $tab= dbitable->new('view',"",'v_names','name_key',
"select N.name_key, " .
" part_name || part_index || part_family || " .
" part_subdomain || part_postfix || " .
" part_domain AS device_name " .
" from p_insertion I, p_name N, p_subdomain S, " .
" p_family F, p_domain D " .
" where I.name_key = N.name_key AND " .
" N.subdomain_key = S.subdomain_key AND " .
" N.family_key = F.family_key AND " .
" S.domain_key = D.domain_key"
)->load();
$tab->pretty_print();
dbitable::disconnect_database();
The following example reads the table "p_insertion" and writes it to a file. Since the original table-object is of the type "table", a new object of the type "file" is created by calling the new
method on the first table-object. Using dbitable-
new(...)> and calling <$ntab->import_table(..)> would have been another possibility to achive this. After the program was executed, you may have a look at the file "TEST.TXT", which is created by this little application.
use strict;
use dbitable;
my $dbname= "DBI:Oracle:bii_par";
my $user="guest";
my $pass="bessyguest";
dbitable::connect_database($dbname,$user,$pass) or die;
my $tab= dbitable->new('table',"",'p_insertion',
'insertion_key')->load();
my $ntab= $tab->new('file',"TEST.TXT","TEST-TAG")->store();
dbitable::disconnect_database();
This script reads the table, adds a line and writes back to the database. Note that the primary key 'insertion_key' must not be specified when add_line
is called, a new primary key is created automagically. Note too, that if you really try to execute this script, it will fail, since the guest-user has no write priviledges. $dbdrv::sql_trace=1
will force the dbitable module to print all SQL commands to the screen, before they are executed.
use strict;
use dbdrv;
use dbitable;
$dbdrv::sql_trace=1;
my $dbname= "DBI:Oracle:bii_par";
my $user="guest";
my $pass="bessyguest";
dbitable::connect_database($dbname,$user,$pass) or die;
my $tab= dbitable->new('table',"",'p_insertion',
'insertion_key')->load();
$tab->add_line(NAME_KEY=> 1,
INTERNAL_NAME=> "XX",
IOC_KEY=> 2,
DESCRIPTION=>"test",
DEVICE_CONDITION=>1);
$tab->pretty_print();
$tab->store();
dbitable::disconnect_database();
This script reads a table from an existing file. Then it reads from the database and kind of compares this with the data from the file. The changed lines are then stored back to the database. The advantage of reading from the database before writing to it is that the SQL "update" command is only executed for lines that have found to be different from the lines stored in the database.
use strict;
use dbdrv;
use dbitable;
$dbdrv::sql_trace=1;
my $dbname= "DBI:Oracle:bii_par";
my $user="guest";
my $pass="bessyguest";
dbitable::connect_database($dbname,$user,$pass) or die;
my $ftab= dbitable->new('file',"TEST.TXT","TEST-TAG")->load();
my $tab = $ftab->new('table',"",'','');
# 1st '': take table-name from $ftab
# 2nd '': take primary key from $ftab
$tab->load(mode=>"add");
$tab->store();
dbitable::disconnect_database();
Goetz Pfeiffer, Goetz.Pfeiffer@helmholtz-berlin.de
perl-documentation, DBI manpage