Connecting to Oracle from Perl - perl

I am trying to connect to Oracle using Perl.
I am trying to connect from a Windows XP machine that has Perl installed. I also have downloaded Oracle SQL Developer and Oracle Instant Client. I can connect to the Oracle DB using Oracle SQL Developer using the TNS connection type.
I use the following Perl.
use DBI;
$db=DBI->connect( "dbi:Oracle", "username", "password" ) or die "Can't connect $DBI::errstr\n";
I get the following error message.
DBI connect('','username',...) failed: ERROR OCINlsEnvironmentVariableGet(OCI_NLS_CHARSET_ID) Check NLS settings etc. at oracle2.pl line3
Cant connect to database ERROR OCINlsEnvironmentVariableGet(OCI_NLS_CHARSET_ID) Check NLS settings etc.
Do I need to do anything with Oracle Instant Client because it does not have an installer. Is there something else that needs configured in Perl?
Thank you for any help provided.
* EDIT *
Are there any variables I need to set at the beginning of the Perl to link to either SQL Developer or Instant Client?

I used a different method to connect Perl to an Oracle DB. I used SQLPlus instead of DBI. This is a command line utility from Oracle that can be called from Perl. Below is a sample of my code. The test.sql file can contain one or multiple queries and must end with exit.
my $connect_string = 'username/password#server'; # connection to the DB
my $file = 'test.sql'; # location of SQL file. The file must end with "exit"
my $sqlcmd = "sqlplus -S $connect_string \#$file"; # sqlcommand
system $sqlcmd; # executes command

With that error message and your piece of code, I'd first check whether it helps to explicitely state the Servername in the first parameter of $db=DBI->connect(.. (if need be, google for some examples).
If that doesn't help, I would then check the value of the environmental variable OCI_NLS_CHARSET_ID.

I had the same problem in cygwin and at the end it could be solved.
In my case it turned out (after a lot of investigation and reading) that the root of the problem was with mixing of versions. The server was 11.2 meanwhile I used the 12.1 Instant Client package to build Oracle.dll for DBD::Oracle. So I downloaded the 11.2 version (from Oracle) and this error message just disappeared!
I have read the Trooble Shooting manual, but it seems 3 packages are needed: Basic, SDK and sqlplus (the later is used by the build process to determine the server version).
Before build some bash variables had to be set:
export ORACLE_HOME=/cygdrive/c/install/instantclient_11_2
PATH+=:"$ORACLE_HOME"
export TNS_ADMIN="$HOME"
The later needed to find oci.dll which is referenced by Oracle.dll. This is added to PATH as Windows looks for PATH to find DLLs not LD_LIBRARY_PATH. File tnsnames.ora can be in $TNS_ADMINdir, or in /var/opt/oracle or in /etc (or some other places). The defined service names can be listed by DBI->data_sources('Oracle').
And voilĂ ! I hope this could help!

I wanted to connect to Oracle XE running in a Docker container (with ports 1521 and 5500 mapped to their host equivalents) and query the Oracle sample database. Here's what worked for me.
#!/usr/bin/perl
use DBI;
# connect to Oracle...
$dbh = DBI->connect("dbi:Oracle:localhost/xepdb1","ot","Orcl1234");
# prepare and execute the SQL statement
$sth = $dbh->prepare("SELECT first_name, last_name FROM employees");
$sth->execute;
# retrieve the results
printf "%-30s %-30s\n", "First Name", "Last Name";
while( my $ref = $sth->fetchrow_hashref() ) {
printf "%-30s %-30s\n", $ref->{'FIRST_NAME'}, $ref->{'LAST_NAME'};
}
exit;

Related

PostgreSQL COPY FROM PROGRAM using ImageMagick

I have 1000 images, and thanks to ImageMagick I can retrieve a lot of information regarding an image by writing "identify -verbose [PATH OF IMAGE]" in the cmd.
I installed ImageMagick with 'legacy on' , to access individual tools rather than the monolithic version of the library.
If I write "identify -verbose C:\\temp\\cbirCorel10k\\1.jpg" in the command prompt it works perfectly, outputting data I need.
My problem is when I insert this code into PROGRAM of PostgreSQL like so :
copy manyline(txt)
from program 'identify -verbose C:\\temp\\cbirCorel10k\\1.jpg'
It gives me this error, and please note that I do have permissions on the image and parent folders to be accessed:
ERROR: program "identify -verbose C:\temp\cbirCorel10k\1.jpg"
failed SQL state: 38000 Detail: child process exited with exit code
1
I want that the output from that command line, is inputted into the table 'manyline' under column 'txt'.
Please note that the following code works well, but I want to make use of the PROGRAM function.
copy manyline(txt)
from 'C:\\temp\\something.txt'
The postgresql server needs permissions to run that program and read that file. it usually runs under username postgres (unless they've changed that recently). this is a "service user" and can be hard to find in the windows GUI; especially on "home" editions of windows. I can't say for sure if granting NETWORK SERVICE access is enough.
easiest solution is to use the psql command-line interface and do
\copy manyline(txt) from program 'identify -verbose C:\\temp\\cbirCorel10k\\1.jpg'
\copy is a psql built-in which runs the command (opens the file etc) as the current user, instead of asking the server to run it. this also works well where the server is not local.

Perl - open a CLI environment and send commands

i'm new with Perl :)
i'm trying to write a simple script just open a CLI environment ( by executing bash command)
and then send a command to that environment (only that environment familiar with this command)
for example:
my linux is running in HP server machine.
if i would like to see the memory configuration so under root user i need
to execute: 'hpasmcli" and then i well get the following environment :
root#xxx:/>% hpasmcli
HP management CLI for Linux (v2.0)
Copyright 2008 Hewlett-Packard Development Group, L.P.
NOTE: Some hpasmcli commands may not be supported on all Proliant servers.
Type 'help' to get a list of all top level commands.
hpasmcli>
and now the need to enter "show dimm":
NOTE: Some hpasmcli commands may not be supported on all Proliant servers.
Type 'help' to get a list of all top level commands.
hpasmcli> show dimm
then i will get the memory configuration in the server.
so i'm tying to write a Perl script to make this simple task.
i tried to use "expect" and "open(FH,"|/sbin/hpasmcli") but i was able just to log in
to the CLI environment and not to send the command "show dimm"
Thank you for your help!
You might need to flush the output buffer after every write:
open my $CMD, "| /sbin/hpasmcli"
or die "Couldn't pipe output to hpasmcli: $!";
my $old_out = select $CMD;
$| = 1; #perl's autoflush global variable which affects the current output file handle
select $old_out;
print {$CMD} "show dimm";

Why does Perl's DBI complain about "failed: ERROR OCIEnvNlsCreate" when I try to connect to Oracle 11g?

I am getting the following error connecting to an Oracle 11g database using a simple Perl script:
failed: ERROR OCIEnvNlsCreate. Check ORACLE_HOME (Linux) env var or PATH (Windows) and or NLS settings, permissions, etc. at
The script is as follows:
#!/usr/local/bin/perl
use strict;
use DBI;
if ($#ARGV < 3) {
print "Usage: perl testDbAccess.pl dataBaseUser dataBasePassword SID dataBasePort\n";
exit 0;
}
my ($user, $pwd, $sid, $port) = #ARGV;
my $host = `hostname`;
my $dbh;
my $sth;
my $dbname = "dbi:Oracle:HOST=$host;SID=$sid;PORT=$port";
openDbConnection();
closeDbConnection();
sub openDbConnection() {
$dbh = DBI->connect ($dbname, $user ,$pwd , { RaiseError => 1}) || die "Database connection not made: $DBI::errstr";
}
sub closeDbConnection() {
#$sth->finish();
$dbh->disconnect();
}
Anyone seen this problem before?
Check your Oracle client configuration (including, as the message says, ORACLE_HOME), check file permissions, etc. It's unlikely that DBI per se has anything to do with the problem, and I know for a fact that DBD::Oracle is compatible with the 11g libraries (at least the 11g InstantClient).
Install the perl module DBD::Oracle
Add use DBD::Oracle; into your perl script.
This made the problem go away for me.
Afther upgrade Oracle form 10.2.0.4 to 10.2.0.5 my Perl-CGI not working, the error.log file of Apache was the error:
DBI connect('DB','user',...) failed: ERROR OCIEnvNlsCreate. Check
ORACLE_HOME (Linux) env var or PATH (Windows) and or NLS settings,
permissions, etc. at ...
OCIEnvNlsCreate. Check ORACLE_HOME (Linux) env var or PATH (Windows)
and or NLS settings, permissions, etc.! at ...
adding the following directive solve the problem:
my $ORACLE_HOME = "/usw/app/oracle/product/10.2";
$ENV{ORACLE_HOME}=$ORACLE_HOME;
Sorry for bringing this thread alive again, but I've been trying to solve this issue for weeks. Nowhere did I find that what finally solved it for me.
Environment: RedHat 6.5, Oracle Instant Client 12.1, Apache 2.2
What solved it for me:
Change the permissions of the directory where Oracle Instant Client is installed., which must also be the value of LD_LIBRARY_PATH. The directory wasn't accessible to "other", just owner and group. This command made the whole difference:
# chmod o+rx INSTANTCLIENT-DIRECTORY
I had been trying to create every possible combination of ORACLE_HOME and LD_LIBRARY_PATH. (Even "unsetting" ORACLE_HOME; I found suggestions that would solve the issue, since Instant Client needed only LD_LIBRARY_PATH and !NOT! ORACLE_HOME.) Nothing helped, until ...
it hit me to look further in the error message:
failed: ERROR OCIEnvNlsCreate. Check ORACLE_HOME (Linux) env var
or PATH (Windows) and or NLS settings, permissions, etc.
permissions being the key word!
Hope this helps someone else!
2021 Update for CentOS 8 etc:-
If you use systemctl, nothing in your environment or Apache setup can pass environment vars to DBI!
you need to edit the /usr/lib/systemd/system/httpd.service file and add appropriate lines like this after the [Service] section:
[Service]
Environment=ORACLE_HOME=/opt/oracle/product/19c/dbhome_1
Then re-start apache as usual:-
/bin/systemctl restart httpd.service
(Vote this up if it helped you: this web page is the #1 google result for this old problem which systemctl "security" has rebirthed)
Check the #!/usr/bin/perl (first line of your script) is the right perl version you wish to use too !
Previous answers don't solve this problem, but they did point me in the right direction: The launched environment was missing the DYLD_LIBRARY_PATH for Oracle instantclient. You can check by calling: launchctl export
or
launchctl getenv variable_name in OS X 10.10
I compared the output from my .bash_profile and found that the path to instanclient wasn't in launchctl PATH and DYLD_LIBRARY_PATH - Once I added them with the following it worked:
launchctl setenv PATH /path/to/instantclient
launchctl setenv DYLD_LIBRARY_PATH /path/to/instantclient
The environment variable used to specify the Oracle libraries may be different from one system to another. On most systems, use LD_LIBRARY_PATH but it may also be LIBPATH (notably on AIX), DYLD_LIBRARY_PATH, or maybe others.
I too went through the same issue. In my case ORACLE_HOME environment variable was incorrect.

Alternative module of Net::SSH::Expect or how to connect remote server and get the output of command

I want to use Net::SSH::Expect in my unix box but unfortunately, it is not available and I am not able to convince the admin to install any perl module. Do you know how could I connect to a remote server using expect.
I know that I can archive that by using python but python is also not avai in my unix box.
Second attempt: though I use expect and shell scripting but the output is missing which is my original problem :Missing output when running system command
Please advise me any alternative module of Net::SSH::Expect so I can check its availibility in my unix box. Or any other way to connect remote server, execute some command and get the output ?
Million thanks.
You do not need your system administrator to install a module in order for you to run it. You can download and install it locally, and use local::lib to use it (as discussed in earlier questions on this site).
Alternatively, have you simply tried:
my $output = `ssh username#host command arguments`;

Starting with Zend Tutorial - Zend_DB_Adapter throws Exception: "SQLSTATE[HY000] [2002] No such file or directory"

I have started to learn Zend Framework with the Book "Zend Framework in Action" in German.
Right there where it starts to get interesting, my PHP Unit Test throws this Error:
"Zend_Db_Adapter_Exception: SQLSTATE[HY000] [2002] No such file or directory"
I can't find any hints through Google searches. I did everything like it is in the book.
Can anyone give me a hint as to where to search for the fault?
Is this a common beginner mistake?
I would say that you have a problem connecting from PHP to MySQL...
Something like PHP trying to find some socket file, and not finding it, maybe ?
(I've had this problem a couple of times -- not sure the error I got was exactly this one, though)
If you are running some Linux-based system, there should be a my.cnf file somewhere, that is used to configure MySQL -- on my Ubuntu, it's in /etc/mysql/.
In this file, there might be something like this :
socket = /var/run/mysqld/mysqld.sock
PHP need to use the same file -- and, depending on your distribution, the default file might not be the same as the one that MySQL uses.
In this case, adding these lines to your php.ini file might help :
mysql.default_socket = /var/run/mysqld/mysqld.sock
mysqli.default_socket = /var/run/mysqld/mysqld.sock
pdo_mysql.default_socket = /var/run/mysqld/mysqld.sock
(You'll need to restart Apache so the modification to php.ini is taken into account)
The last one should be enough for PDO, which is used by Zend Framework -- but the two previous ones will not do any harm, and can be useful for other applications.
If this doesn't help : can you connect to your database using PDO, in another script, that's totally independant of Zend Framework ?
i.e. does something like this work (quoting) :
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
If no, the problem is definitly not with ZF, and is a configuration / installation problem of PHP.
If yes... Well, it means you have a problem with ZF, and you'll need to give us more informations about your setup (like your DSN, for instance ? )
Do not assume your unix_socket which would be different from one to another, try to find it.
First of all, get your unix_socket location.
$ mysql -u root -p
Enter your mysql password and login your mysql server from command line.
mysql> show variables like '%sock%';
+---------------+---------------------------------------+
| Variable_name | Value |
+---------------+---------------------------------------+
| socket | /opt/local/var/run/mysql5/mysqld.sock |
+---------------+---------------------------------------+
Your unix_soket could be diffrent.
Then change your php.ini, find your php.ini file from
<? phpinfo();
You maybe install many php with different version, so please don't assume your php.ini file location, get it from your 'phpinfo';
Change your php.ini:
mysql.default_socket = /opt/local/var/run/mysql5/mysqld.sock
mysqli.default_socket = /opt/local/var/run/mysql5/mysqld.sock
pdo_mysql.default_socket = /opt/local/var/run/mysql5/mysqld.sock
Then restart your apache or php-fpm.
Try setting host=127.0.0.1 on your db settings file, it worked for me! :)
Hope it helps!
i had this problem when running the magento indexer in osx.
and yes its related to php problem when connecting to mysql through pdo
in mac osx xampp, to fix this you have create symbolic link to directory /var/mysql, here is how
cd /var/mysql && sudo ln -s /Applications/XAMPP/xamppfiles/var/mysql/mysql.sock
if the directory /var/mysql doesnt exist, we must create it with
sudo mkdir /var/mysql
Im also suffered from this problem & simply, by adding port number after the ip address saved me.
$dsn = 'mysql:dbname=sms_messenger;host=127.0.0.1:8889';
$user = 'root';
$password = 'root';
This works for Mac OS
If you don't know your mysql port number, then
You can easily find the port number on MAMP home page
OR
Type following command while running the MAMP server to switch the terminal into mysql
OMBP:mamp Omal$ /Applications/MAMP/Library/bin/mysql --host=localhost -uroot -proot
Then type
mysql> SHOW GLOBAL VARIABLES LIKE 'PORT';
This error because mysql is trying to connect via wrong socket file
try this command for MAMP servers
cd /var/mysql && sudo ln -s /Applications/MAMP/tmp/mysql/mysql.sock
or
cd /tmp && sudo ln -s /Applications/MAMP/tmp/mysql/mysql.sock
and this commands for XAMPP servers
cd /var/mysql && sudo ln -s /Applications/XAMPP/tmp/mysql/mysql.sock
or
cd /tmp && sudo ln -s /Applications/XAMPP/tmp/mysql/mysql.sock
It looks like mysql service is either not working or stopped.
you can start it by using below command (in Ubuntu):
service mysql start
It should work! If you are using any other operating system than Ubuntu then use appropriate way to start mysql