2

How do I do a SELECT on a SQL Server 2005 from a Perl script?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
ˈoʊ sɪks
  • 897
  • 1
  • 7
  • 10

3 Answers3

4

You will need to use DBI and you are probably best using the DBD::ODBC provider from (CPAN). If you don't know about DBI, then you need to read up about that. There's a book (Programming the Perl DBI) which is old but still valid.

Then something like the following:

use strict;
use warnings;
use DBI;

# Insert your DSN's name here.
my $dsn = 'DSN NAME HERE'

# Change username and password to something more meaningful
my $dbh = DBI->connect("DBI:ODBC:$dsn", 'username', 'password')

# Prepare your sql statement (perldoc DBI for much more info).
my $sth = $dbh->prepare('select id, name from mytable');

# Execute the statement.
if ($sth->execute)
{
    # This will keep returning until you run out of rows.
    while (my $row = $sth->fetchrow_hashref)
    {
        print "ID = $row->{id}, Name = $row->{name}\n";
    }
}

# Done. Close the connection.
$dbh->disconnect;
Martin
  • 9,674
  • 5
  • 36
  • 36
Nic Gibson
  • 7,051
  • 4
  • 31
  • 40
  • 1
    If you're on a Unix-ish platform, DBD::ODBC is likely to be a pain, and it's probably better to use DBD::Sybase with FreeTDS. (Well, UnixODBC was pretty painful last time I tried it) – araqnid May 22 '09 at 13:03
  • @araqnid - I was going to mention FreeTDS but decided to avoid complicating this. I've had the joy of UnixODBC myself :) – Nic Gibson May 22 '09 at 13:52
2

Here's a basic example using DBI (edited after comment):

use DBI;

my $dbh = DBI->connect("dbi:Sybase:database=<dbname>;server=<servername>",
    <user>, <password>, 
    { PrintError => 0, RaiseError => 1 });
my $sth = $dbh->prepare( "select field from table" );
my $result = $sth->execute();
while( my $result = $sth->fetchrow_hashref ) {
    print $result->{field};
}
$sth->finish;
$dbh->disconnect;

Hoping to see other answers with a simpler solution :)

Andomar
  • 232,371
  • 49
  • 380
  • 404
  • 1
    You don't generally need to specify dbi_connect_method. And I'd recommend using "PrintError =>0, RaiseError => 1" so that SQL errors are thrown... especially since you don't do any error checking ;) You can even shortcut by just saying "for my $row in (@{ $dbh->selectall_arrayref("select field from table", { Slice => {} })}) { print "$row->{field}\n"; } If you're going to use fetchrow_hashref or its friends, worth setting "FetchHashKeyName => 'NAME_lc'" when connecting to the DB too, some people insist on using CamelCase for column names. But apart from all that, fine :) – araqnid May 22 '09 at 13:02
0
        #
        # ------------------------------------------------------
        # run a passed sql and retun a hash ref of hash refs
        # ------------------------------------------------------
        sub doRunSqlGetHashRef {

            my $self                   = shift ;
            my $sql                    = shift ;

            my $hsr_meta               = {} ;
            my $hsr                    = {} ;
            my $rowid = 0 ;
            my $flag_filled_hsr_meta   = 0 ;
            my $hsr_meta_colid         = 0 ;

            use DBI;

            my $dbs = "dbi:ODBC:DRIVER=FreeTDS;DSN=DEV_MSSQLSRV_DSN";
            # verify by :
            # isql -v DEV_MSSQLSRV_DSN user pwd

            my $dbh = DBI->connect($dbs, $db_user, $db_user_pw)
                or die "CONNECT ERROR! :: $DBI::err $DBI::errstr $DBI::state $!\n";

            if (defined($dbh)) {

                # Prepare your sql statement (perldoc DBI for much more info).
                my $sth = $dbh->prepare( $sql ) ;

                # Execute the statement.
                if ($sth->execute) {
                # This will keep returning until you run out of rows.
                    while (my $row = $sth->fetchrow_hashref)  {

                        # fill in the meta hash reference with the col names
                        if ( $flag_filled_hsr_meta == 0 ) {
                            for (@{$sth->{ 'NAME' }}) {
                                # debug ok print "$_ => $row->{$_}\t";
                                $hsr_meta->{ $hsr_meta_colid } = $_ ;
                                $hsr_meta_colid++ ;
                                $flag_filled_hsr_meta = 1 ;
                            }
                        }
                        # p ( $row ) ; # row level debug ...
                        $hsr->{ $rowid } = $row ;
                        $rowid++ ;
                    }
                }
                # Done. Close the connection.
                $dbh->disconnect;

                # debug ok p( $hsr_meta ) ;

                return ( $hsr_meta , $hsr )  ;
            }
            else {
                print "Error connecting to database: Error $DBI::err - $DBI::errstr\n";
            }

        }
        #eof sub doRunSqlGetHashRef
Yordan Georgiev
  • 5,114
  • 1
  • 56
  • 53