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

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

Related

Perl connection to Google Cloud MySQL Not working

A MySQL server was setup in Google Cloud and SSL was enabled, however when trying to connect it gives this error
SSL connection error: The certificate is NOT trusted. The certificate issuer is unknown. The name in the certificate does at trial.pl line 24.
This is the error I am seeing, I downloaded the certificates directly from the GCP website.
use strict;
use warnings;
use DBI;
my $driver = "mysql";
my $database = "raw_data";
my $database_url = "GCP_IP";
my $userid = "GCP_username";
my $password = "GCP_pass";
my $table = "raw_data_test";
my $key = "client-key.pem";
my $cert = "client-cert.pem";
my $ca = "server-ca.pem";
my $ssl = "mysql_ssl=1;mysql_ssl_client_key=$key;mysql_ssl_client_cert=$cert;mysql_ssl_ca_file=$ca";
my $dsn = "DBI:$driver:database=$database:$database_url;$ssl";
my $dbh = DBI->connect($dsn, $userid, $password) or die $DBI::errstr;
print("IT WORKS\n");
my code is exactly as above (I omitted the identifying information about the server)
When the ssl string is removed from the dsn it connects without issue because SSL is not fully enforced. I run the code in the directory where the certs are. So is there something wrong with my code? Or is this something to do GCP?
Additionally, if I use a mysql command directly in terminal to connect to the database with the certs/keys, it connects without error. I am not sure how to narrow down where the issue is.

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)

Error while connecting to Sybase DB

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 );

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";
}