cjacksonjr has asked for the wisdom of the Perl Monks concerning the following question:

When I use the buildHistory sub routine. The info is just added to the current table. I need to clear the contents of the table and insert the new data. Is it better to drop table or delete table contents and how is it done?
#! /usr/local/bin/perl -w # A perl program to do things with the alarm log use FileHandle; use IPC::Open2; use Symbol; # use Tk; use Sybase::CTlib; use Time::Local; use strict; my(%dispatch) = (); my(%systemNames); systemNames(); # fill in the hash my $dbAlarm=new Sybase::CTlib 'ops','opsops','OPSYB1',''; $dbAlarm->ct_sql("use TomTest"); %dispatch = (help =>\&help,buildhistory=>\&buildHistory,createdbtables +=>\&createDbTables); my(@lines, $line); my $count = 0; #logMe(); my $numberOfArgs = @ARGV; if($numberOfArgs == 0) { help(); exit 1; } my($what) = shift(@ARGV); my($whatLower) = $what; $whatLower =~ tr/[A-Z]/[a-z]/; if ($what eq undef) { help(); exit 1; } if(exists($dispatch{$whatLower})) { &{$dispatch{$whatLower}}(@ARGV); exit 0; } help(); exit; sub buildHistory { # no input # for each entry in the notifAlarmLog Table build a history record my $sql = "SELECT distinct topic from notifAlarmEntry WHERE category like 'WARNING' OR category like 'OK NOW'"; my(@sources, $source); @sources = $dbAlarm->ct_sql($sql); my ($TLCount) = 0; # Keeps track of Transaction Log (TL) my ($StartStopCount) = 0; my ($esequence,$eutime,$edtime,$esource,$eprocess,$ecategory,$etopic +) = (0,1,2,3,4,5,6); foreach $source (@sources) { $TLCount++; # Incremnt TL $sql = "SELECT * from notifAlarmEntry where topic like '$source->[ +0]' ORDER by datetime"; # print "$sql\n"; my(@records,$recordA,$recordB); @records = $dbAlarm->ct_sql($sql); if (($TLCount%1000) == 0) { $sql = "dump transaction TomTest with truncate_only"; $dbAlarm->ct_sql($sql); } # these should now be in pairs, see that they are my($index); for ($index=0; $index<@records; ) { $recordA = $records[$index++]; $recordB = $records[$index]; $StartStopCount++; # Keeps track of each pair of Alarms (Start/S +top) print "$StartStopCount alarm(s) occurred \n"; my $result = GetPairs($recordA, $recordB); if($result < -1) { # maybe out of order $result = GetPairs($recordB, $recordA); } $index++ if($result == 0); print "Problem with $recordA->[$etopic] $recordA->[$esequence] $ +recordA->[$eutime] $recordA->[$edtime] $recordA->[$esource] $recordA +->[$eprocess] $recordA->[$ecategory] and $recordB->[$etopic] $recordB +->[$esequence] $recordB->[$eutime] $recordB->[$edtime] $recordB->[$e +source] $recordB->[$eprocess] $recordB->[$ecategory] \n" if($result ! += 0); } } } sub GetPairs { # two notifAlarmEntry records (Alarm: Start/Stop) # Input is two notifAlarmEntry records that should be an WARNING and + OK NOW # make a history if they are OK else return an error # return -1 if names are wrong (not same PS) # return -2 if 1st message is not WARNING # return -3 if 2nd message is not OK NOW # use strict; # my ($esequence,$eutime,$edtime,$esource,$eprocess,$ecategory,$etop +ic) = (0,1,2,3,4,5,6); my ($recordA) = shift; my ($recordB) = shift; # print "record A $recordA->[0] $recordA->[1] $recordA->[2] $reco +rdA->[3] $recordA->[4] $recordA->[5] $recordA->[6] \n"; # print "record B $recordB->[0] $recordB->[1] $recordB->[2] $reco +rdB->[3] $recordB->[4] $recordB->[5] $recordB->[6] \n"; return -1 if($recordA->[6] ne $recordB->[6]); return -2 if($recordA->[5] ne 'WARNING'); return -3 if($recordB->[5] ne 'OK NOW'); # found a pair my ($f1,$adoName,$f3) = split(":",$recordA->[6]); my $SiteWideName= $main::systemNames{$adoName} . " : $f3"; # print ":$adoName: :$SiteWideName: \n"; my $sql = "INSERT notifAlarmLog (name, AlarmStart, AlarmStop, UnixTi +meStart, UnixTimeStop, SiteWideName) values ('$recordA->[6]','$record +A->[2]', '$recordB->[2]', $recordA->[1], $recordB->[1], '$SiteWideNam +e')"; # print "$sql\n"; $dbAlarm->ct_sql($sql); return 0; } sub systemNames { # fill in the systemName hash use strict; my $dbAdo=new Sybase::CTlib 'harmless','harmless','OPSYB1','paramPro +pTable'; $dbAdo->ct_sql("use serverAdo"); my $sql = "SELECT name,systemName from adoInst where name like 'psWa +tch%'"; my(@rows,$row); @rows = $dbAdo->ct_sql($sql); foreach $row (@rows) { $main::systemNames{$row->[0]} = $row->[1]; # print "<$row->[0]> <$row->[1]> \n"; } } sub createDbTables { use strict; my $tblName = "notifAlarmLog"; print "Create table name $tblName\n"; my $sql = "CREATE TABLE $tblName( name varchar(65) not null, AlarmStart datetime not null, AlarmStop datetime not null, UnixTimeStart int not null, UnixTimeStop int not null, SiteWideName varchar(35) null )"; } sub help { # display help for this tool print "NotifAlarmTool- A program to do a variety of operations inte +racting with the Notif log. The first argument is a command verb. So +me commands require additional arguments. List of commands <buildHistory> makes history records from the alarm records. <createDbTables> Creates an alarm and an alarmHistory table in the TomTest database. Of course the old alarm and alarmH +istory records are gone. "; }

Replies are listed 'Best First'.
Re: dropping or deleting tables
by mpeppler (Vicar) on Jul 19, 2002 at 16:10 UTC
    You have three possibilities:
    • drop/create table
    • delete (possibly with a where clause?)
    • truncate table
    The one you choose depends on how your database is set up, and what sort of recoverability you need.

    Using drop table/create table has the advantage of not invalidating the transaction log. The disadvantage is that any procedure/trigger/view that refers to the table will need to be re-resolved the next time it runs. In bad cases such procedures may need to be reloaded.

    Using delete ... from table offers the best recoverability in case of errors as the operation is logged. This is also it's largest drawback as it makes it slower than the other options, and if the table is large you may need a large transaction log.

    Using truncate table is the fastest, but it is a minimally logged operation. A truncate table command invalidates the transaction log, which means that you must take a full database backup after the truncate to be able to recover the database after the truncate (assuming you don't have trunc log on checkpoint turned on in that database, of course).

    Hope this helps...

    Michael

Re: dropping or deleting tables
by Joost (Canon) on Jul 19, 2002 at 14:35 UTC
    Deleting the content is probably a lot more efficient then dropping.

    Delete the content by running DELETE FROM tablename - I'm unfamiliar with Sybase::CTlib but with DBI you do something like:

    $dbh = DBI->connect(@database_parameters); $dbh->do("DELETE FROM tablename");
    -- Joost downtime n. The period during which a system is error-free and immune from user input.
Re: dropping or deleting tables
by erasei (Pilgrim) on Jul 19, 2002 at 14:39 UTC
    It seems to be Database Question Day in the Monestary today.

    I don't have any experience with Sybase at all, but have several years with MySQL, so, I can at least tell you what it does, and chances are, it will be close to home.

    If you want to delete everything in the table, you can either drop the table and recreate it, or just DELETE FROM. If the table is very large, the drop/recreate is going to be faster. If the table is pretty small, a DELETE * FROM table will work pretty fast, just make sure you do not have a WHERE clause in there. A DELETE * FROM table WHERE id > 1 will run a lot slower, since it will have to compare each row, instead of just dropping the lot of them.

    As with all worries of speed, a local benchmark will always have the best answer.