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

I am writing a script to reduce the size of our databases. It will copy out tables from database A to database B. The process uses bcp in and out. Database B is considerably smaller and will need to grow when necessary. So I do a check after each table to make sure that there is still enough space in database B. If the amount of space falls below a certain percentage I then increase the size of database B. After the the size is increased I move into a new sub routine that verifies that structure of the new table to be copied into is the same as the original table. This process fails as a result of not being able to execute a stored procedure. Giving the error that the proc is not found. I have verified the proc and it works fine. I believe that the reason it is failing is because it trys to run this proc while the alter database is still executing in the database. How can I make sure the process completes before I move into the next subroutine.
  • Comment on How to determine when sybase process complete

Replies are listed 'Best First'.
Re: How to determine when sybase process complete
by Joost (Canon) on Apr 19, 2005 at 17:00 UTC
      This is the sub routine that alters the sybase database. the alter command can run for a extended period of time.
      sub _grow_db() { my ( $dbh, $dbname, $increase, $tran_size, $data_pool, $log_pool ) = @ +_; my $log_increase = int ( $increase * $params->get("Device.Log.Percent" +) / 100 ); my $max_tran_size = int ( $params->get("Max.Tran.Size") ); my $sql = "use master"; $$dbh->do($sql) or $app->log($FATAL, "Can't do SQL statement [ $sql ] :: $DBI::errst +r"); $app->log($INFO,"Altering database $dbname. Increasing data segment b +y $increase MB"); my $sql="alter database $dbname on "; foreach my $device ( @$data_pool ) { next if ( $$device{free} == 0 ); if ( $increase >= $$device{free} ) { $sql .= "$$device{name}=$$device{free},"; $increase -= $$device{free}; $$device{free} = 0; } else { $sql .= "$$device{name}=$increase,"; $$device{free} -= $increase; $increase = 0; } last if ( $increase == 0 ); } if ( $tran_size < $max_tran_size ) { $app->log($INFO,"Altering database $dbname. Increasing log segment by +$log_increase MB"); $sql =~ s/,$//; $sql .= " log on "; foreach my $device ( @$log_pool ) { next if ( $$device{free} == 0 ); if ( $log_increase >= $$device{free} ) { $sql .= "$$device{name}=$$device{free},"; $log_increase -= $$device{free}; $$device{free} = 0; } else { $sql .= "$$device{name}=$log_increase,"; $$device{free} -= $log_increase; $log_increase = 0; } last if ( $log_increase == 0 ); } } $sql =~ s/,$//; #$$dbh->do($sql) # or $app->log($FATAL,"Can't do SQL statement [ $sql ] :: $DBI::err +str"); my $sth = $$dbh->prepare($sql) or $app->log($FATAL,"Can't prepare SQL statement [ $sql ] :: $DBI: +:errstr"); $sth->execute(); $sth->finish();
      this is the output from a alter database command.
      alter database D_IGT_IMP on data023device = 43 log on
      log003device = 5
      2> go
      Extending database by 22016 pages on disk data023device
      Extending database by 2560 pages on disk log003device
      Warning: Using ALTER DATABASE to extend the log segment
      will cause user thresholds on the log segment within 128
      pages of the last
      chance threshold to be disabled.
      } This is the sub routinne that fails if run after the alter database.
      sub get_table_info() { my ( $dbh, $table ) = @_; my @columns = (); my $sql = "exec sp_getcol2 $table"; my $sth = $$dbh->prepare( $sql ) or $app->log($FATAL,"Can't prepare SQL statement [ $sql ] :: $DBI: +:errstr"); $sth->execute() or $app->log($FATAL,"Can't prepare SQL statement [ $sql ] :: $DBI: +:errstr"); while ( my (@results) = $sth->fetchrow_array() ) { my $col_ref = { 'name' => $results[0], 'type' => $results[1], 'length' => $results[2], 'prec' => $results[3], 'scale' => $results[4], 'null' => $results[5], 'identity' => $results[8] }; push @columns, $col_ref; } $sth->finish(); return \@columns; }
Re: How to determine when sybase process complete
by mpeppler (Vicar) on Apr 20, 2005 at 05:16 UTC
    I don't have the time to go into detail right now - but this is strictly a Sybase issue, and I suggest that you ask on one of the Sybase news groups at news://forums.sybase.com/, for example in public.sybase.ase.administration.

    Michael

Re: How to determine when sybase process complete
by Anonymous Monk on Apr 20, 2005 at 09:42 UTC
    It's been a few years ago that I used Sybase. But I can think of four possible ways, if I remember the Sybase details correctly:
    1. Get the list of processes. See if your alter database is still running.
    2. When doing an alter database, Sybase is sending messages. If you are using isql, these message will be displayed. If you're using Sybperl, you can set up a message handler (a callback) which will be triggered on each message. Use that to track progress. I do not know whether DBD::Sybase gives you access to the messages. (These are the same messages as will appear in the Sybase log file).
    3. Watch the Sybase log file.
    4. Sybase uses a system table to keep track of which disk partitions it's using for the database (syssegments, IIRC). This is probably your best bet, if the table gets updated after the alter database finishes. But it's too long ago to recollect whether it does before, or after.
    I'm sure mpeppler will correct me where I'm wrong.