I know there is a similar question: Connect to SQL Server 2005 from Perl and do a SELECT , but I tried the accepted answer and am unable to get it to work.
Assuming I have a db named test, and would love to do a select from mytable
(select id, name from mytable)
Code is from the link above with updated dsn:
use strict;
use warnings;
use DBI;
# Insert your DSN's name here.
my $dsn = 'database=test'
# 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;
This is what I got when running the script:
Can't connect to data source 'ODBC::database=test' because I can't work out what
driver to use (it doesn't seem to contain a 'dbi:driver:' prefix and the DBI_DR
IVER env var is not set) at script.pl line 9
Looks like the problem is in the dsn but I have no idea how to fix it (I am on sql 2005, active perl 5.10 and windows xp).
Edit:
I used the following code to verified whether ODBC is installed.
use DBI;
print join (", ", DBI->installed_versions);
Output:
It looks like ODBC is indeed in the list.
ADO, CSV, DBM, ExampleP, File, Gofer, ODBC, SQLite, Sponge, mysql
What am I missing?
I got the same error with SQLite just now, and it looks like you did the same thing wrong as me. Note the number of colons in the first argument - this is the wrong format:
my $db = DBI->connect('DBI::SQLite::dbname=testing.db', '', '', {RaiseError => 1, AutoCommit => 1});
There should actually only be two colons, not two pairs of colons in the first argument:
my $db = DBI->connect('DBI:SQLite:dbname=testing.db', '', '', {RaiseError => 1, AutoCommit => 1});
Question answered despite its age because it's still top of the results in Google for this particular error message
Try setting your DSN to something like:
my $dbh = DBI->connect("dbi:ODBC:test", 'username', 'password')
If that doesn't work, ensure you have DBD::ODBC installed by running:
perl -MDBI -e 'DBI->installed_versions;'
Assume SQL server is located on local server, connection below can be right:
my $DSN = "driver={SQL Server};Server=127.0.0.1;Database=test;UID=sa;PWD=123456";
my $dbh = DBI->connect("dbi:ODBC:$DSN");
Related
I use to use sqlsrv_connect but changed it to PDO.
Now i got this syntax error when using åäö.
When i used sqlsrv_connect i could do this:
SELECT Order, [Benämning], [Vår ref] FROM table
and it worked.
Now i'm trying to figure out how to do it with PDO.
So i tried:
SELECT Order, [Benämning], Antal FROM table
And got this error:
Operand type clash: text is incompatible with float
And i tried:
SELECT Order, Benämning, Antal FROM table
And i got error:
Incorrect syntax near '�'.
In the connection i added utf8:
$sql = new PDO("odbc:Driver=$driver;server=$serverName,$port;Database=$database;ConnectionPooling=0", $uid, $pwd,
array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
)
);
Now, when pasting this i can se: PDO::MYSQL_ATTR_I... I'm connecting to SQL.. not MYSQL. Can this be the problem?
If i remove the "Benämning" column and just select columns without åäö or space the select works just fine.
UPDATE
I got åäö to work with sqlsrv instead of odbc.
You simply need to use the same driver (PHP Driver for SQL Server) and the same connection options when you create the PDO instance.
<?php
...
try
$sql = new PDO("sqlsrv:Driver=$driver;server=$server,$port;Database=$database", $uid, $pwd);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
...
} catch( PDOException $e ) {
...
}
try {
$sql = "SELECT [Vår ref], ... FROM ...";
$stmt = $conn->prepare($sql);
$stmt->execute();
} catch( PDOException $e ) {
...
}
?>
Some additional notes:
You need to quote the column name ([Vår ref]) to make the string literal a valid SQL Server identifier.
Use driver specific PDO connection attributes (PDO::SQLSRV_xxx) to add driver specific features. The PDO::MYSQL_ATTR_INIT_COMMAND option is useful if you connect to MySQL instance.
I need to test the structure of my SQLite database which is composed by a unique table with let's say 2 columns (id, name). I can't figure out the SQL query to get the table schema of my database.
I am able to get all the content of the database using the DBI method selectall_arrayref(). However it only returns an array containing the values inside my database. This information is useful but I would like to have a SQL query which returns something like id, name (Basically, the table schema).
I tried the following queries : SHOW COLUMNS FROM $tablename but also SELECT * from $tablename (This one returns all the table content).
Here is my implementation so far :
# database path
my $db_path = "/my/path/to/.database.sqlite";
my $tablename = "table_name";
sub connect_to_database {
# Connect to the database
my $dbh = DBI->connect ("dbi:SQLite:dbname=$db_path", "", "",
{ RaiseError => 1, AutoCommit => 0 },
)
or confess $DBI::errstr;
return $dbh;
}
sub get_database_structure {
# Connect to the database
my $dbh = &connect_to_database();
# Get the structure of the database
my $sth = $dbh->prepare("SHOW COLUMNS FROM $tablename");
$sth->execute();
while (my $inphash = $sth->fetrow_hashref()) {
print $inphash."\n";
}
# Disconnect from the database
$dbh->disconnect();
}
# Call the sub to print the database structure
&get_database_structure();
I expect the output to be the structure of my table so id, name but I raise an error : DBD::SQLite::db prepare failed: near "SHOW": syntax error
I can't find the good query. Any comments or help would be greatly appreciated.
Thanks !
What you're looking for is really just the SQL lite query for the table and column information. This answer SQLite Schema Information Metadata has the full details if this query doesn't work for you, but under the assumption you're using whatever the 'recent' version mentioned in one of the answers is, you can do something like this:
# Get the structure of the database
my $sth = $dbh->prepare("<<END_SQL");
SELECT
m.name as table_name,
p.name as column_name
FROM sqlite_master AS m
JOIN pragma_table_info(m.name) AS p
ORDER BY m.name, p.cid
END_SQL
$sth->execute();
my $last = '';
while (my $row = $sth->fetchrow_arrayref()) {
my ($table, $column) = #$row;
if ($table ne $last) {
print "=== $table ===\n";
$last = $table;
}
print "$column\n";
}
After digging through the community answers I finally find a solution using the pragma table_info.
sub get_database_structure {
# Connect to the database
my $dbh = &connect_to_database ();
# Return the structure of the table execution_host
my $sth = $dbh->prepare('pragma table_info(execution_host)');
$sth->execute();
my #struct;
while (my $row = $sth->fetchrow_arrayref()) {
push #struct, #$row[1];
}
# Disconnect from the database
$dbh->disconnect ();
return #struct;
}
It returns a list of the columns name present in the table execution_host.
Thanks for the help !
I am facing this problem perl DBD::ODBC rollback ineffective with AutoCommit enabled at and while looking at the problem , I found that a very basic thing is failing with Perl::DBI using DBD::ODBC on sql server. But i am not sure if this wont happen with any other driver.
The problem is that when I create a #temp table using $dbh->do and when i try to access the same #temp table using another $dbh->do , i am getting the below error. Also this does not happen all the time , but only intermittently.
Invalid object name '#temp'
$dbh->do("SELECT ... INTO #temp FROM ...");
$dbh->do("INSERT INTO ... SELECT ... FROM #temp");
The second do fails with 'Invalid object name '#temp''
Kindly help me with the problem.
Not that it answers your question but it might help. The following works for me.
#
# To access temporary tables in MS SQL Server they need to be created via
# SQLExecDirect
#
use strict;
use warnings;
use DBI;
my $h = DBI->connect();
eval {
$h->do(q{drop table martin});
$h->do(q{drop table martin2});
};
$h->do(q{create table martin (a int)});
$h->do(q{create table martin2 (a int)});
$h->do('insert into martin values(1)');
my $s;
# this long winded way works:
#$s = $h->prepare('select * into #tmp from martin',
# { odbc_exec_direct => 1}
#);
#$s->execute;
# and this works too:
$h->do('select * into #tmp from martin');
# but a prepare without odbc_exec_direct would not work
print "NUM_OF_FIELDS: " . DBI::neat($s->{NUM_OF_FIELDS}), "\n";
$s = $h->selectall_arrayref(q{select * from #tmp});
use Data::Dumper;
print Dumper($s), "\n";
$h->do(q/insert into martin2 select * from #tmp/);
$s = $h->selectall_arrayref(q{select * from martin2});
print Dumper($s), "\n";
I was having this problem as well. I tried all of the above but it didnt matter. I stumbled upon this http://bytes.com/topic/sql-server/answers/80443-creating-temporary-table-select-into which solved my problem.
What's happening is that ADO is opening a second connection behind
your back. This has really not anything to do with how you created the
table.
The reason that ADO opens an extra connection, is because there are
rows waiting to be fetched on the first connection, so ADO cannot
submit a query on that connection.
I assume that Perl DBI is doing the same, so based on this assumption, here's what I did and it worked perfectly fine:
my $sth = $dbh->prepare('Select name into #temp from NameTable');
$sth->execute();
$sth->fetchall_arrayref();
$sth = $dbh->prepare('Select a.name, b.age from #temp a, AgeTable b where a.name = name');
$sth->execute();
my ($name,$age)
$sth->bind_columns(\$name,\$age);
while ( $sth->fetch())
{
# processing
}
I have a PostgreSQL database in use for a complex php web site (And VB.Net/C# management applications) which require access to execute stored procedures on a Microsoft SQL Server 2008 database. The method chosen to perform this interaction is to use plperl functions within the PostgreSQL database to wrap access to the MSSQL stored procedures.
We are using the perl DBI module to handle the data retrieval from MSSQL database.
I am a neophyte when it comes to perl in general and specifically when using it with PostgreSQL. I have created the function shown below to return a set of composite type
CREATE TYPE "public"."permissions_return" AS (
"rolename" TEXT,
"roledescription" TEXT,
"permissionname" TEXT,
"permissiondescription" TEXT
);
The stored proc called from within the function works fine and returns data when run through a slightly different perl script run from the command-line, or directly from the MSSQL Server. I have not been able to figure out how to return data from my function when using:
SELECT * FROM fn_perltest(153);
The result is always an empty set.
CREATE FUNCTION fn_perltest(integer) RETURNS SETOF permissions_return AS $$
use strict;
use DBI;
my $data_source = q/dbi:ODBC:Production/;
my $user = q/afunkyusername/;
my $password = q/afunkierpassword/;
my $dbh = DBI->connect($data_source, $user, $password);
my $sth = $dbh->prepare(q/up_DCORsel_getUserPermissionByUserID $1 ;/);
$sth->execute();
while ( defined ( my $row = $sth->fetchrow_array() )) {
return next ({
rolename => $row->{RoleName},
roledescription => $row->{RoleDescription},
permissionname => $row->{PermissionName},
permissiondescription => $row->{PermissionDescription}
});
}
return;
$$ LANGUAGE 'plperlu'
If this helps, Postgres is running on a Fedora 13 server. Access to MSSQL Server is configured using unixODBC with the freetds driver. Access to the MSSQL server has been tested and works fine using the isql command-line tool and a simple perl script.
Any ideas would be greatly appreciated. I'm concerned I may run out of hair to pull out.
Regards
Shane
This doesn't answer your question directly, but I have used dblink when attempting to have one database query data in another database. It seemed to work well. Obvious plperlu has a lot more power than dblink, but I don't have any experience with it (just perl and postgresql :-)
dblink can be found in postgresql's contrib directory.
Using sql server 2008 I am getting and invalid precision value error in the following perl script:
use DBI;
$idx = '12345';
$query = 'if exists (select * from tbl where idx = ?) select top 10 * from tbl';
my $h = $dbh->prepare($query) or die "Couldn't prepare query: " . $dbh->errstr;
$h->execute($idx) or die "Couldn't execute statement: " . $h->errstr;
Note however that if I try this instead
use DBI;
$query = 'if exists (select * from tbl where idx = \'12345\') select top 10 * from tbl';
my $h = $dbh->prepare($query) or die "Couldn't prepare query: " . $dbh->errstr;
$h->execute() or die "Couldn't execute statement: " . $h->errstr;
then it works. I am really confused at how the ? in the query could possibly be causing an invalid precision error.
Thanks for any help anyone can provide.
Based on this article, please try the following:
You need to import the SQL type constants from DBI
and specify that SQL_LONGVARCHAR as the type of the data to be added to the memo field.
To do that you do:
$dbh->bind_param(1, $idx, SQL_LONGVARCHAR);
Binding with a specific type overrides what DBD::ODBC decides. DBD::ODBC will bind the parameter based on what comes back from SQLDescribeParam. Sometimes SQL Server's SQLDescribeParam fails, especially in cases where you are using functions or subselects. The SQL Server ODBC driver takes your SQL and rearranges it to attempt to end up with something like "select idx from tbl" then it looks at the columns to answer SQLDescribeParam calls. I'm betting the SQL Server ODBC driver fails to rearrange your SQL in this case and either SQLDescribeParam failed or returned the wrong information. If you enable tracing in DBD::ODBC we could probably see this happening.