Error while connecting to Sybase DB - perl

I have a perl script which connects to a Sybase db server (alias for server - MYDATABASESERVER). My code is:
exec perl -w -x
#!perl
use Sybase::DBlib;
use Mail::Sendmail;
use Env qw(DSQUERY DBNAME DBUSER DBPASSWD);
$dbh = &execRemoteSQL($sql_text);
sub execRemoteSQL
{
my ($sqlText) = #_;
my ( $ret, $retS );
local ($dbh) = undef;
$dbh = new Sybase::DBlib $DBUSER, $DBPASSWD, $DSQUERY;
if ( !(defined $dbh) )
{
print STDERR "execRemoteSQL(): Failed To Create DB Handle for :\n";
print STDERR " SERVER = $DSQUERY\n";
print STDERR " DATABSE = $DBNAME\n";
exit(-1);
}
.
.
.
When i provide the server name as MYDATABASESERVER (value of DSQUERY), I get the error in the If statement, but it connects properly to the server with name as MYDB.
Wanted to know if there is any constraint on the server name length or is it due to something else.
Here is the error messsage i am getting:
DB-Library error:
Unknown host machine name.
execRemoteSQL(): Failed To Create DB Handle for :
SERVER = MYDATABASESERVER
DATABSE = my_db
The server alias is defined properly because i am able to connect to the db using isql.

I don't think the length of the server name is too long here.
What is your exact error message?
Maybe the MYDATABASESERVER server-alias name is not defined properly in the Sybase-specific "interfaces" config file. It resides in dir $SYBASE/$SYBASE_OCS. What does it say about MYDATABASESERVER (should be 2 lines)?
In any case:
Don't use DBLib, it is really old and deprecated. I think the maintainer of the Sybperl/DBLib and DBD::Sybase modules, only still supports the Sybase::DBLib code to make life easier for client programmers who have to deal with old programs, and to keep legacy applications compatible with new releases of Sybase ASE.
You should use DBI and DBD::Sybase instead. 99% of all perl/sybase code on the internet uses DBI.

Can you try the following syntax instead? :
$dbh = Sybase::DBlib->new( $DBUSER, $DBPASSWD, $DSQUERY );

Related

How can I specify the port number with DBD::ODBC?

I currently use the following code to connect to a database in my Perl script:
my $dsn = 'dbi:ODBC:MYDATABASE';
my $database = 'uat_env';
my $user = 'user';
my $auth = 'password';
my $dbh = DBI->connect($dsn, $user, $auth, {
RaiseError => 1,
AutoCommit => 1
}) or die("Couldn't connect to database");
$dbh->do('use '.$database);
Now the port has changed from 1433 to 40450.
I am having trouble changing the port in the DSN. I thought this change would work but I am receiving a "DSN not found" error:
my $dsn = 'dbi:ODBC:MYDATABASE;Port=40450';
Any idea why this isn't working?
There are two formats for a DBI data source string for ODBC. You can say either
dbi:ODBC:DSN=MYDATABASE
or you can abbreviate that to
dbi:ODBC:MYDATABASE
which is what you have. If you use just the DSN then you can't add any more parameters, so your dbi:ODBC:MYDATABASE;Port=40450 is looking for DSN MYDATABASE;Port=40450 which clearly doesn't exist
The proper way to do this is to set up a new DSN which has a copy of all the parameters of MYDATABASE, but with a different port name
At a guess, I would say you may be able to write
dbi:ODBC:DSN=MYDATABASE;Port=40450
but I can't be sure and I have no way of testing
If your requirements are simple then you can supply all of the parameters instead of a DSN, like this
dbi:ODBC:Driver={SQL Server};Server=11.22.33.44;Port=40450
but you will have to supply the correct driver if you aren't using a SQL Server ODBC connection, and other parameters may be necessary
You should start by examining the values in the MYDATABASE DSN and go from there

Informix error in Perl: ISAM: 107: ISAM error: record is locked. at test_db_connectivity.pl line 14

I'm trying to connect to our database in our production environment. I am getting the 107 ISAM error: record is locked . I have checked various articles on what it could be, but no luck. I double checked the database details with our DBA and the information is correct.
FYI - Also the first error previous to the "record is locked" error I received was SQL: -931: Cannot locate web1_tcp service/tcp service in /etc/services. at test_db_connectivity.pl line 13. . I worked with our SA to get that entered and that is no longer appearing. Can anyone offer any guidance on the ISAM 107 error? Is my connection string wrong? There shouldn't be a lock because I am not even opening a connection to the database.
test_db_connectivity.pl:
#/usr/bin/perl -w
use DBI;
use strict;
use DBI qw(:sql_types);
use DBD::Informix qw(:ix_types);
my $driver = "Informix";
my $database = "web1";
my $dsn = "DBI:$driver:dbname=$database";
my $userid = "user";
my $password = "password";
print "I got this far!\n";
my $dbh = DBI->connect($dsn, $userid, $password, {RaiseError => 1}) or die $DBI::errstr;
print "Opened db successfully\n";
$dbh->disconnect();
Some of the variables set:
export INFORMIXDIR=/opt/informix
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$INFORMIXDIR/lib:$INFORMIXDIR/lib/cli:$INFORMIXDIR/lib/esql:$INFORMIXDIR/lib/tools
export INFORMIXSERVER=web1
INFORMIX SQLHOSTS FILE:
#dbservername nettype hostname servicename options
web1 onsoctcp 10.199.***.* web1dev1_tcp
etc/services FILE:
web1dev1_tcp 1533/tcp # Port assigned to database
virtual-places 1533/tcp # Virtual Places Software
web1dev1_tcp 1533/udp # Port assigned to database
On Linux, there is a system error 107:
107 (ENOTCONN): Transport endpoint is not connected
It is hard to distinguish that from a C-ISAM error 107 (the number is the same). However, in context, I think the ENOTCONN is far more likely to be the problem than
ISAM ERROR 107: record is locked.
I observe that you're using a notation in $dsn that DBD::Informix doesn't test for:
my $dsn = "DBI:$driver:dbname=$database";
The dbname= portion of that is incorrect. You should use:
my $dsn = "DBI:$driver:$database";
Note that the DBI spec (when I last looked) said that what follows the driver name is driver-specific. You could submit an enhancement request.
However, on my working system, when I use the dbname=stores notation, the error I get is:
DBI connect('dbname=stores', '',...) failed: SQL: -354: Incorrect database or cursor name format. at dbname-dsn.pl line 8.
That's quite different. You say you got:
SQL: -931: Cannot locate web1_tcp service/tcp service in /etc/services. at test_db_connectivity.pl line 13
The error message is quite explicit. You need an entry in /etc/services such as:
web1_tcp 9088/tcp
At the moment, you do not have such an entry, and therefore the connection is not even attempted, much less successful.

Not able to connect to .accdb file using perl

I am trying to connect to access 2007 database using perl. Below is the code that I tried executing
use DBI;
$path='T:\a\abc.accdb';
$datasource = "driver={Microsoft Access Driver (*.mdb,*.accdb)};DBQ=$path";
$dbh = DBI->connect("dbi:ODBC:$datasource", '', '') || die "Error connecting: $!";
$query="select name from receiver";
$exe=$dbh->prepare($query) or die "cannot prepare";
$exe->execute or die "cannot execute";
$a=$exe->fetchall_arrayref();
foreach $aa(#{$a})
{
print #$aa;
}
but the execution fails with the below error
DBI connect('driver={Microsoft Access Driver(*.mdb,*.accdb)};DBQ=T:\a\abc.accdb','',...)failed: [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (SQL-IM002) at test.pl line 5.
Error connecting: at test.pl line 5.
can someone please guide me how to resolve this issue.
Your driver name is missing a space. ODBC is very fussy about that. Try
$datasource = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=$path";
Also, NAME is a reserved word in Access SQL so you may need to use
$query="select [name] from receiver";
My experience with DBI:ODBC is somewhat dated but I would suggest the following:
Check the driver names in the ODBC datasource setup and make sure
that you have the spelling right. (spaces and all) - Maybe set up a
DSN and use that instead - more reliable
Check that the file exists (I don't think that is the problem from
the error message)
Capitalization on the Driver/Dbq (not likely but we are dealing with
MS)

How do I connect with Perl to SQL Server?

I have a user id, password, database name and datasource details. I want to connect with Perl to a MSSQL server. I just used the following snippet, but I am getting an error.
#!/usr/bin/perl -w
use strict;
use DBI;
my $data_source = q/dbi:ODBC:192.168.3.137/;
my $user = q/bharani/;
my $password = q/123456/;
# Connect to the data source and get a handle for that connection.
my $dbh = DBI->connect($data_source, $user, $password)
or die "Can't connect to $data_source: $DBI::errstr";
My error is:
DBI connect('192.168.3.137','bharani',...) failed: [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (SQL-IM002) at my sqlconnect.pl line 14
Can't connect to dbi:ODBC:192.168.3.137: [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (SQL-IM002) at mysqlconnect.pl line 14.
The SQL server runs on another system, I am just trying to connect with above details. Please tell me, should I crease DSN in my system, or is anything missing in my program?
Everything following 'dbi:ODBC:' in your connection string is passed to the ODBC driver. For MSSQL, try this connection string:
DBI->connect("dbi:ODBC:Driver={SQL Server};Server=192.168.3.137;UID=$user;PWD=$password")
You can find some more alternatives on connectionstrings.com
I am on Ubuntu (20.04) and followed the instructions to install SLQ Server in a docker container:
https://learn.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker?view=sql-server-ver15&pivots=cs1-bash
I created the TestDB and the table Inventory as per the tutorial.
I installed the ODBC driver following
https://learn.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-ver15
The driver library file was /opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.5.so.2.1
With that, the following script successfully connects to the DB and returns the content of the table:
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
my $user = 'SA';
my $password = '<YourNewStrong#Passw0rd>';
my $dbh = DBI->connect("dbi:ODBC:Driver={/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.5.so.2.1};Server=localhost;Database=TestDB;UID=$user;PWD=$password");
my $sth = $dbh->prepare("SELECT * FROM Inventory");
$sth->execute();
while ( my #row = $sth->fetchrow_array ) {
print "#row\n";
}

Why can't I connect to my CAS server with Perl's AuthCAS?

I'm attempting to use an existing CAS server to authenticate login for a Perl CGI web script and am using the AuthCAS Perl module (v 1.3.1). I can connect to the CAS server to get the service ticket but when I try to connect to validate the ticket my script returns with the following error from the IO::Socket::SSL module:
500 Can't connect to [CAS Server]:443 (Bad hostname '[CAS Server]')
([CAS Server] substituted for real server name)
Symptoms/Tests:
If I type the generated URL for the authentication into the web browser's location bar it returns just fine with the expected XML snippet. So it is not a bad host name.
If I generate a script without using the AuthCAS module but using the IO::Socket::SSL module directly to query the CAS server for validation on the generated service ticket the Perl script will run fine from the command line but not in the browser.
If I add the AuthCAS module into the script in item 2, the script no longer works on the command line and still doesn't work in the browser.
Here is the bare-bones script that produces the error:
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use AuthCAS;
use CGI::Carp qw( fatalsToBrowser );
my $id = $ENV{QUERY_STRING};
my $q = new CGI;
my $target = "http://localhost/cgi-bin/testCAS.cgi";
my $cas = new AuthCAS(casUrl => 'https://cas_server/cas');
if ($id eq ""){
my $login_url = $cas->getServerLoginURL($target);
printf "Location: $login_url\n\n";
exit 0;
} else {
print $q->header();
print "CAS TEST<br>\n";
## When coming back from the CAS server a ticket is provided in the QUERY_STRING
print "QUERY_STRING = " . $id . "</br>\n";
## $ST should contain the received Service Ticket
my $ST = $q->param('ticket');
my $user = $cas->validateST($target, $ST); #### This is what fails
printf "Error: %s\n", &AuthCAS::get_errors() unless (defined $user);
}
Any ideas on where the conflict might be?
The error is coming from the line directly above the snippet Cebjyre quoted namely
$ssl_socket = new IO::Socket::SSL(%ssl_options);
namely the socket creation. All of the input parameters are correct. I had edited the module to put in debug statements and print out all the parameters just before that call and they are all fine. Looks like I'm going to have to dive deeper into the IO::Socket::SSL module.
As usually happens when I post questions like this, I found the problem. It turns out the Crypt::SSLeay module was not installed or at least not up to date. Of course the error messages didn't give me any clues. Updating it and all the problems go away and things are working fine now.
Well, from the module source it looks like that IO::Socket error is coming from get_https2
[...]
unless ($ssl_socket) {
$errors = sprintf "error %s unable to connect https://%s:%s/\n",&IO::Socket::SSL::errstr,$host,$port;
return undef;
}
[...]
which is called by callCAS, which is called by validateST.
One option is to temporarily edit the module file to put some debug statements in if you can, but if I had to guess, I'd say the casUrl you are supplying isn't matching up to the _parse_url regex properly - maybe you have three slashes after the https?