PEPPLER.ORG
Michael Peppler
Sybase Consulting
Menu
Home
Sybase on Linux
Install Guide for Sybase on Linux
General Sybase Resources
General Perl Resources
Freeware
Sybperl
Sybase::Simple
DBD::Sybase
BCP Tool
Bug Tracker
Mailing List Archive
Downloads Directory
FAQs
Sybase on Linux FAQ
Sybperl FAQ
Personal
Michael Peppler's resume

sybperl-l Archive

Up    Prev    Next    

From: Michael Peppler <mpeppler at peppler dot org>
Subject: Re: ct_sql woes
Date: Oct 25 2002 4:33PM

On Fri, 2002-10-25 at 09:01, Sabherwal, Balvinder (MBS) wrote:
> Guru's
> 
> I have a script as below which is failing to print the results after the
> query execution. I have tried to run the query using isql and it returns the
> result back fine. 
> 
> Is there anything wrong I'm doing in here?? the scalar report 0 elements in
> the array and ct_callback reports no error after the query executions. All
> I'm trying to do is, select the data from one database and insert it into
> the other database.

Let's see:


#!c:\perl/bin/perl.exe
############################################################################
#
# SCRIPT:    mt_busctr.pl
# DESCRIPTION:
#            This program gets the business counters from middletier
database
#            and puts them in the matrics database for Sybase.
#
# AUTHOR:    Balvinder Sabherwal
# CREATED:   Oct 25, 2002
#
# 
#
# MODIFICATION HISTORY:
#
#
#
############################################################################

# import all modules
use Sybase::CTlib;

use strict;   ###### ALWAYS USE THIS!!!! Avoids countless typos!!!

# We only need to set the callback once
ct_callback(CS_SERVERMSG_CB, \&srv_cb);
ct_callback(CS_CLIENTMSG_CB, \&msg_cb);

my $dbh = Sybase::CTlib->ct_connect(user, "password", "SYB_DBSRVR"); 
if ($dbh){
        print "Connected to mt server\n";
}

$dbh->ct_sql("use middletierdb");

$sql = "
select
    MiddleTierServiceDesc,     
    convert(varchar,convert(datetime,convert(varchar(12),RequestDate))),
    convert(varchar,datepart(hour,RequestDate)),
    convert(varchar,count(*)) 
from ServiceReqStatus a (index NClServiceReqStatus),
     MiddleTierServiceType b
where a.RequestDate between
           convert(datetime,substring(getdate(),1,12)) and getdate()
  and a.MiddleTierServiceTypeCd = b.MiddleTierServiceTypeCd
group by MiddleTierServiceDesc,
         convert(datetime,convert(varchar(12),RequestDate)),
         datepart(hour,RequestDate)
";

print "$sql \n";

my $DBRow = $dbh->ct_sql($sql);

#print "Executed the sql \n $DBRow \n printing the rows \n";

# NOTE: ct_sql() returns a *reference* to an array, so we need to 
# de-reference it to get the items in the array.
my $a = scalar @$DBRow;
print "There are $a elements in array\n";

# Each row in the array is a reference to the row
# so @$Row represents the array of column for that row
foreach my $Row ( @$DBRow ) {
        print "values ==>> @$Row \n";
}

my $dbh = Sybase::CTlib->ct_connect(user, "password", SYB_DBSRVR); ##
Connect to the server.

if ($dbh){
        print "Connected to the matrics server \n";
        $dbh->ct_sql("use perfmondb");
}

foreach my $Row ( @$DBRow ) {
        print "@$Row \n";
        my ($BusCtr, $SDt, $hr, $Value) = @$Row;
        print "$BusCtr, $SDt, $hr, $Value \n";
        $dbh->ct_sql("exec proc_busctr_data_save '$BusCtr' , '$SDT' ,
'$hr'
,  $Value");
} 



sub msg_cb
{
    my($layer, $origin, $severity, $number, $msg, $osmsg, $dbh) = @_;

    printf "\nOpen Client Message: (In msg_cb)\n";
    printf "Message number: LAYER = (%ld) ORIGIN = (%ld) ",
               $layer, $origin;
    printf "SEVERITY = (%ld) NUMBER = (%ld)\n",
               $severity, $number;
    printf "Message String: %s\n", $msg;
    if (defined($osmsg))
    {
        printf "Operating System Error: %s\n", $osmsg;
    }
    CS_SUCCEED;
}


sub srv_cb
{
    my($dbh, $number, $severity, $state, $line, $server,
       $proc, $msg) = @_;
    # If $dbh is defined, then you can set or check attributes
    # in the callback, which can be tested in the main body
    # of the code.

    printf "\nServer message: (In srv_cb)\n";
    printf "Message number: %ld, Severity %ld, ",
               $number, $severity;
    printf "State %ld, Line %ld\n", $state, $line;
    if (defined($server))
    {
        printf "Server '%s'\n", $server;
    }
    if (defined($proc))
    {
        printf " Procedure '%s'\n", $proc;
    }
    printf "Message String: %s\n", $msg;  CS_SUCCEED;
}

__END__


OK - some comments.

Always, always, ALWAYS "use strict". This forces you to "declare" the
variables you want to use (via "my"), and to quote all strings. This is
a *good* thing. In your original script you had the following:

$DBRow = $dbh->ct_sql(...);
$a = scalar @DBRow;

$DBRow and @DBRow are NOT the same variable - of course $a would be 0 in
this case, because @DBRow has never been populated!

ct_sql() returns a reference to an array, where each element is a
reference to a row. So it isn't necessary to join the data in the query
(as you do with a "|" character).

Instead, you can do this:

my $data = $dbh->ct_sql(...);
foreach my $row (@$data) {
    my ($col1, $col2, $col3) = @$row;
    ... now you have columns 1, 2 and 3 for this particular row, and 
        you can process them ...
}

Hope this clears things up a little...

Michael
-- 
Michael Peppler / mpeppler@peppler.org / http://www.mbay.net/~mpeppler
mpeppler@zetatools.com / ZetaTools, Inc / http://www.zetatools.com
ZetaTools: Call perl functions as Sybase stored procedures!