PDO ODBC query on linked tables doesn't give any results - php

I would like to use PDO ODBC to get datas from .mdb file. This works fine when querying on "normal" tables, however it always fails on linked tables, whatever the query is.
Connexion :
$pdo = new PDO("odbc:Driver={Microsoft Access Driver (*.mdb)};Dbq=$mdb;SystemDB=$mdw;", $user, $pass);
Ex :
A normal table "test" (id, name)
Query : SELECT * FROM test
It works, I get the expected rows
A linked table "linked_test"
Query : SELECT * FROM linked_test
It doesn't return anything
But on attached/linked/synchronized tables i can't get any results, the PDOStatement just return the queryString, no result to fetch.
These tables are synchronized to a Oracle Database.
Then the question is how should I proceed to get results from theses tables ?
Thanks.
Sorry for my bad english...

Unfortunately, what you are attempting simply won't work from PHP. You will need to create a separate connection to the Oracle database and pull the information directly from there.

Related

PHP and MSSQL Multiple Database Connections

I'm having a weird issue with connecting to the master database twice.
$devdb01 = $this->load->database('master',true);
$dbstate = $this->load->database('mastercheck',true);
I have 2 different connection id's but it seems if i'm running a query on the master database it won't execute another query even though its a separate database connection. Basically i'm trying to use a SP that runs a restore database and then run another query checking if the database is still in a restoring state.
I run the queries like the following:
$dbresult=$devdb01->query($query);
$dbcheck=$dbstate->query($checkquery);
echo $devdb01->conn_id;
echo $dbstate->conn_id;
$query = "EXECUTE master..sqlbackup '-SQL \"RESTORE DATABASE $dbname FROM DISK = [$restoredir$backupselected] WITH REPLACE, MOVE [$dataname] TO [$datadir$dbname$dataprepend] , MOVE [$logname] TO [$logdir$dbname$logprepend]\"'";
$dbresult=$devdb01->query($query);
$checkquery="SELECT state_desc from sys.databases where [name]='$dbname'";
$dbcheck=$dbstate->query($checkquery);
var_dump($dbcheck);
I just get an output of bool(false) for that var_dump. I verified that the connection id's are different after connecting to the database.
When I try to check the result of the 2nd query I get an error saying i'm calling a member function on a non-object so it must not be executing the query. If I reverse the order it will execute the other query like expected.
I can't tell if this is a PHP limitation? I'm using code igniter so it could be something related to that as well. I tested with SQL Management Studio and it works fine in separate query windows connecting multiple times to the master database. What i'm trying to accomplish is to come up with a way to run this first query then not do anything until I know that query is completed first.
Update
It appears if I turn off Persistent Database connections by disabling pconnect it will use the same connection twice.
This is the output from the connection id with pconnect set to false:
Resource id #52Resource id #52

Need help to solve mysql and odbc query issue

Hello im developing an application where data comes from MSSQL database. Here using php odbc connection i get all the needed data to work with app. But now i have a problem:
Im looking for:
All data from mssql (assume) mssql_Table_A will be listed in this app, each row will be given with checkbox so user can check the data required, after checking When he hit save checked data will be stored in local MySQL database (assume) mysql_table_A.
So next time when he again wants few more data, this app will list all the data from mssql_table_A which dont exists in mysql_table_A.
Problem is:
If both the dataflwo were from MYSQL i would have done this where easily by using mysql select query
mysql_query("SELECT * FROM mysql_table_a WHERE NOT EXISTS (SELECT * FROM mysql_table_B WHERE thisID != thatID)")
But here how do i check data exists in mysql table and list the data from odbc mssql database.
Please help me to resolve this problem.
Thank You..
You need to use mssql_, sqlsrv_ or PDO functions to connect to MSSQL. mysql_ functions are strictly for MySQL.
Microsoft SQL Server Driver for PHP
Microsoft SQL Server
Microsoft SQL Server Functions (PDO_SQLSRV)
You will need two separate connections if you are fetching data from both.
Alternatively, you can connect to MySQL from MSSQL using an ODBC connection and perform your query on the MSSQL side.
The other answers have told you how to connect the two databases but based on your comments you still want to know how to do the comparison.
I have to assume you've got at least one column which you can uniquely identify rows in table_a which are not in table_b. If you link mysql in MS SQL Server like one answer said you can
select * from mssql.table_a where unique_column not in (select unique_column from mysql.table_b)
but this works because mssql is linked to mysql in mssql i.e., you can do one query and mssql will do the join for you.
If for some reason you cannot or don't want to link mysql to ms sql via a linked table the easiest way would be if you had some sort of timestamp in table_a. Let's say every record written into table_a has a timestamp of when it was inserted:
mysql connection does select max(timestamp) into X from mysql.table_b
mssql connection does select * from mssql.table_a where timestamp > X
There may be other ways if we knew a bit more about your data.

Is my method of fetching MySql data using prepared statements inefficient and taxing on my server?

I was informed by someone senior in our company today that the PHP code I have written for performing prepared statements on a MySQL database is "inefficient" and "too taxing on our server". Since then I find myself in the difficult position of trying to understand what he meant and then to fix it. I have no contact to said person for four days now so I am asking other developers what they think of my code and if there are any areas that might be causing bottlenecks or issues with server performance.
My code works and returns the results of my query in the variable $data, so technically it works. There is another question though as to whether it is efficient and written well. Any advice as to what that senior employee meant or was referring to? Here is the method I use to connect and query our databases.
(Please note, when I use the word method I do not mean a method inside a class. What I mean to say is this how I write/structure my code when I connect and query our databases.)
<?php
// Create database object and connect to database
$mysqli=new mysqli();
$mysqli->real_connect($hostname, $username, $password, $database);
// Create statement object
$stmt=$mysqli->stmt_init();
// Prepare the query and bind params
$stmt->prepare('SELECT `col` FROM `table` WHERE `col` > ?');
$stmt->bind_param('i', $var1);
// Execute the query
$stmt->execute();
// Store result
$stmt->store_result();
// Prepare for fetching result
$rslt=array();
$stmt->bind_result($rslt['col']);
// Fetch result and save to array
$data=array();
while($stmt->fetch()){
foreach($rslt as $key=>$value){
$row[$key]=$value;
}
$data[]=$row;
}
// Free result
$stmt->free_result();
// Close connections
$stmt->close();
$mysqli->close();
?>
Any advice or suggestions are useful, please do contribute and help out even if you are only guessing. Thanks in advance :)
There are two types of code that may be inefficient, the PHP code and the SQL code, or both.
For example, the SQL is a problem if the `col` column isn't indexed in the database. This puts lots of load on the database because the database has to scan very many rows to answer queries. If `col` isn't indexed in the given query, then all of the rows in the table would be scanned. Also, if the value passed in isn't very selective, then many rows will have to be examined, perhaps all of the rows, as MySQL will choose a table scan over an index scan when many rows will be examined. You will need to become familiar with the MySQL EXPLAIN plan feature to fix your queries, or add indexes to the database to support your queries.
The PHP would be a problem if you followed something like the pattern:
select invoice_id from invoices where customer_id = ?
for each invoice_id
select * from line_items where invoice_id = ?
That kind of pattern will lead to "over querying" the database, which puts extra load on it. Instead use a join:
select li.* from invoices i join line_items li using (invoice_id)
Ask your database administrator to turn on the slow query log and then process it with pt-query-digest
You can use pt-query-digest to report on queries that are expensive (take a long time to execute) and also to use it to report by frequency to detect over querying.

pdo mysql select statement working on one table while it is not working on other

I am having a strange problem.
I am using PDO prepared statement.
I have two tables with the name of TABLE1 AND TABLE2.
TABLE1 is copied from another db with its data.
TABLE2 is created using phpmyAdmin,
Both Tables are in the same Database.
I am running a Select statement using PDO prepare and its working fine on TABLE1 (which is copied from another DB) while it is not working on TABLE2 (which is created using phpmyadmin). No error and No exception. Strange?
does PDO prepare statement requires any specific type of table? or another setting which i don't know?
I find the solution myself. actually pdo requires fully qualified name to access table which was created using phpmyadmin.
so run the select statement using Following queries.
SELECT * FROM DB1.TABLE2 (successfully return the result set)
While I can access my Copied table (TABLE1) from another database without using DB1.
SELECT * FROM TABLE1 (successfully return the result set)
Cheers!

How do I construct a cross database query in PHP?

In our last episode (How I constructed a cross database query in MySQL) I learned how to construct a cross database query in MySQL. This worked great but when our hero tried to use this newfound knowledge in PHP he found his best friend FAIL waiting for him.
I took a look at mysql_select_db for PHP. This seems to imply that if I want to use MySQL with PHP, I have a couple of choices:
Use mysql_select_db but be stuck with only using one db at a time. This is our current setup and putting a database as a namespace identifier doesn't seem to work (it works fine in the MySQL shell so I know it's not a problem with our MySQL server setup).
Don't use mysql_select_db. From some of the examples I've seen, this seems to mean that I have to specify the db for every query that I make. This makes sense since I haven't used mysql_select_db to tell PHP what db I want to access. This also makes sad since I don't want to go through all my code and prepend a db name to every query.
Is there something better than this? Is there a way for me to do a cross db MySQL query in PHP without having to something crazy like (2)?
CLARIFICATION: None of the proposed answers actually let me do a cross db query. Instead, they allow me to access two different DBs separately. I want a solution that allows me to do something like SELECT foreign_db.login.username, firstname, lastname from foreign_db.login, user where ... NOT just make different queries to different DBs. For what it's worth, (2) doesn't work for me.
You will need your databases to run on the same host.
If so, you should be able to use mysql_select_db on your favourite/default db and manually specify a foreign database.
$db = mysql_connect($hots, $user, $password);
mysql_select_db('my_most_used_db', $db);
$q = mysql_query("
SELECT *
FROM table_on_default_db a, `another_db`.`table_on_another_db` b
WHERE a.id = b.fk_id
");
If your databases run on a different host, you won't be able to join directly. But you can then make 2 queries.
$db1 = mysql_connect($host1, $user1, $password1);
$db2 = mysql_connect($host2, $user2, $password2);
$q1 = mysql_query("
SELECT id
FROM table
WHERE [..your criteria for db1 here..]
", $db1);
$tmp = array();
while($val = mysql_fetch_array($q1))
$tmp[] = $val['id'];
$q2 = mysql_query("
SELECT *
FROM table2
WHERE fk_id in (".implode(', ', $tmp).")
", $db2);
After reading your clarification, I am under the impression that you actually want to query tables residing in two separate MySQL server instances. At least, your clarification text:
SELECT foreign_db.login.username, firstname, lastname from foreign_db.login, user where
suggests that you want to run one query while being logged in as two users (which may or may not reside on the same mysql server instance).
In your question, you said you wanted to query data from two different databases, but it is important to realize that one MySQL instance can have many, many databases. For multiple databases managed by the same mysql instance, the solution proposed in the question you linked to simply works: just prefix the table name with the name of the databases, separating database and table names with a dot: <db-name>.<table-name>.
But, like i pointed out, this only works if:
all databases you access in one query reside on the same server - that is, are managed by the same MySQL instance
the user that is connected to the database has the right privileges to access both tables.
Scenario1: databases on same host: grant appopriate privileges and qualify table names
So if the tables actually reside on the same mysql instance, there is no need for a second login or connection - simply grant the database user you use to connect to the datbase the appropriate privileges to select from all tables you need. You can do that with the GRANT syntax, documented here: http://dev.mysql.com/doc/refman/5.1/en/grant.html
For example, GRANT SELECT ON sakila.film TO 'test'#'%' will allow the user test#% to select data from the film table in the sakila database. After doing that, said user can refer to this table using sakila.film (so-called qualified table name), or if the current database is set to sakila, simply as film
Scenario2: databases managed by different MySQL instances: FEDERATED engine
If the tables you want to access are actually managed by two different MySQL instances, there is one trick that may or may not work, depending on your configuration. Since MySQL 5.0 mysql supports the FEDERATED storage engine. This lets you create a table that is not actually a table, but a peephole to a table on a remote server. This engine is documented here: http://dev.mysql.com/doc/refman/5.1/en/federated-storage-engine.html
For example, if you know there is this table in the misc database on the remote host:
CREATE TABLE t (
id int not null primary key
, name varchar(10) not null unique
)
you can make a local 'pointer' to that remote table using this:
CREATE TABLE t (
id int not null primary key
, name varchar(10) not null unique
)
ENGINE = FEDERATED
CONNECTION='mysql://<user>#<remote-server>:<remote-port>/misc/t';
Unfortunately, the FEDERATED engine is not always available, so you have to check first if you can even use that. But suppose it is, then you can simply use the local table t in your queries, just like any other table, and MySQL will communicate with the remote server and perform the appropriate operations on the physical table on the other side.
Caveat: there are several optimization issues with FEDERATED tables. You should find out if and to what extent these apply to you. For instance, applying a WHERE to a federated table can in many cases result in the entire table contents being pullled over the wire to your local server, where the actual filtering will be appplied. Another issue is with table creation: you have to be very sure that the definitions of the federated table and the table it is pointing to match exacty, except for the ENGINE clause (and CONNECTION). If you have for example a different character set, the data may arrive completely garbled after travelling over the wire.
If you want to use FEDERATED tables, do read this article http://oreilly.com/pub/a/databases/2006/08/10/mysql-federated-tables.html to decide if its right for your particular use case.
If you think you do need it, I have a utility to create federated tables here: http://forge.mysql.com/tools/tool.php?id=54
Scenario3: can't use FEDERATED, but tables on different MySQL instances
Finally, if you have tables on different MySQL instances, but cannot for some reason use the federated table engine, your a out of luck I'm afraid. You are simply going to have to execute queries to both MySQL instances, receive the results and do something intelligent with it in PHP. depending on your exact requirements, this may be a perfectly viable solution
I guess you need to decide for yourself which part of my answer best appeals to your problem, and add a comment in case you need more help. TIA Roland.
A solution might be to :
use mysql_select_db to select the "default" (i.e. most used) database
and specify the DB name only in queries that have to work with the "second" (i.e. least used) database.
But this is only a viable solution if you have one DB that's more used than the other...
Out of curiosity : did you try establishing several connections to your DB server -- i.e. one for each database ?
You might be able to :
connect to the first DB with mysql_connect, and, then, select the first DB with mysql_select_db
and, then, connect to the second DB, passing true for the new_link parameter of mysql_connect if necessary, and, then, selecting the second DB with mysql_select_db
Then, work with the connection identifier returned by the first, or second, call to mysql_connect, depending on which DB you want to issue queries.
As a sidenote : the "best" / "cleanest" solution would be not using mysql_* functions directly, but working with some kind of ORM framework, that would have the ability to work with several DB connections at the same time (not sure, but maybe Doctrine can do that -- it's a real good ORM)
I set up tables in separate test databases as follows:
mysql> use test;
mysql> create table foo as select 42 as id from dual;
mysql> create database test2;
mysql> use test2;
mysql> create table bar as select 42 as id from dual;
I ran the following PHP script with MySQL 5.1.41 and PHP 5.3.1 on Mac OS X:
<?php
$link = mysql_connect('localhost', 'root', 'XXXX')
or die('There was a problem connecting to the database.');
mysql_select_db('test');
$sql = "SELECT * FROM foo JOIN test2.bar USING (id)";
if (($result = mysql_query($sql)) === FALSE) {
die(mysql_error());
}
while ($row = mysql_fetch_array($result)) {
print_r($row);
}
This test succeeds. The result is the join between the two tables in separate databases.
You should always be able to select from table(s) qualified by their respective database names in SQL. The mysql API in PHP does not restrict you to querying one database.
You should always be able to omit the database qualifier for the "current" database, which you declare with mysql_select_db().
Maybe this is the code that you want
//create links
$link1 = mysql_connect('localhost', 'mysql_user', 'mysql_password');
$link2 = mysql_connect('localhost', 'mysql_user', 'mysql_password');
//set db on every link
mysql_select_db('foo', $link1);
mysql_select_db('bar', $link2);
//do query with specified link
$result1 = mysql_query($query1,$link1);
$result2 = mysql_query($query2,$link2);
Note that we didn't do a mysql_select_db between queries , and we didn't use the database name in the query either.
Whenever you are SELECTing from multiple tables you have to sepcify an alias. So it's pretty simple from there:
SELECT
a.id, a.name, a.phone,
b.service, b.provider
FROM
`people` AS a,
LEFT JOIN
`other_database`.`providers` AS b ON a.id = b.userid
WHERE
a.username = 'sirlancelot'
As others on this page have mentioned, the database must be on the same host and instance. You cannot query a database from another server with this syntax.
The less verbose option you have is provided by the MySQL Manual itself:
The following example accesses the
author table from the db1 database and
the editor table from the db2
database:
USE db1;
SELECT author_name, editor_name FROM author, db2.editor
WHERE author.editor_id = db2.editor.editor_id;
You can use option two: "Don't use mysql_select_db" and then use mysql_db_query instead of mysql_query ... which is a simple find and replace.
Best of luck!
I've just tried this simple code in my computer and it works perfectly:
<?php
$conn = mysql_connect('localhost', 'root', '....');
mysql_select_db('aliro');
$sql = 'select * ' .
'from aliro_permissions a ' .
'left join cmsmadesimple.cms_permissions b on a.id=b.permission_id ';
$res = mysql_query($sql)
or die(mysql_error());
while($row = mysql_fetch_assoc($res)){
print_r($row);
}
?>
(Of course, the query itself is meaningless, it's just an example.)
So I can't really see what your exact problem is. If you want a syntax that's simpler that this, you'll have to provide an example of what kind of SQL you want to write.

Categories