3

I need to execute this SQL query:

SELECT DISTINCT
    logger.hcp_id,
    logger.rep_id,
    logger.type,
    session_brand_presentation.ID,
    session_brand_presentation.brand_id,
    session_brand_presentation.createdAt,
    session_brand_presentation.modifiedAt
FROM
    archive_pfizer.logger
        JOIN
    pdone_legacy.session_brand_presentation ON logger.session_id = session_brand_presentation.local_session_id

WHERE
    logger.type = 'email_sent';

As you may already notice I am querying to different databases: archive_pfizer and pdone_legacy. I know that DSN needs a DB name for create the PDO object then as title say: How do I execute a PDO statement when there are two databases involve in the same query?

Very important I am asking how to achieve this from PHP using PDO, I was able to execute the query successfully from MySQL/MariaDB command line and/or using any GUI.

UPDATE

Here is the code I was working on based on @RyanVincent answer:

$config = parse_ini_file('config.ini', true);
define('EOL', (PHP_SAPI == 'cli') ? PHP_EOL : '<br />');
$DBASE = $config['database']['DBASE'][0];
$pdo = setupDB($config, $DBASE);

$sql = 'SELECT DISTINCT logger.hcp_id, logger.rep_id, logger.type, session_brand_presentation.ID, session_brand_presentation.brand_id, session_brand_presentation.createdAt, session_brand_presentation.modifiedAt FROM archive_pfizer.logger JOIN pdone_legacy.session_brand_presentation ON logger.session_id = session_brand_presentation.local_session_id WHERE logger.type = "email_sent"';

foreach($pdo->query($sql) as $row) {
    var_export($row);
    echo EOL;
}

But I got this error:

PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'pdone_legacy.session_brand_presentation' doesn't exist'

Apparently it's taking pdone_legacy.session_brand_presentation as a table when it's a database, in the example provided is the same as testmysql, any advice?

UPDATE 2

Trying the same SQL query but using aliases didn't work either:

$sql = 'SELECT DISTINCT
            lg.hcp_id,
            lg.rep_id,
            lg.type,
            sbp.ID,
            sbp.brand_id,
            sbp.createdAt,
            sbp.modifiedAt
        FROM
            archive_pfizer.logger AS lg
                JOIN
            pdone_legacy.session_brand_presentation AS sbp ON lg.session_id = sbp.local_session_id

        WHERE
            lg.type = "email_sent"';

Got exactly the same issue as before.

UPDATE 3

Ok, perhaps I will got killed after say this but was my bad all the time. I was connecting to a server where DB pdone_legacy exists but that DB in fact hasn't session_brand_presentation table and that is what PDO was saying all the time. Anyway thanks to anyone here and both queries are valid.

ReynierPM
  • 17,594
  • 53
  • 193
  • 363
  • what database is you using? – rray Sep 23 '15 at 17:06
  • @RyanVincent databases are in the same host and use the same credentials (bad but I am using root for now) – ReynierPM Sep 23 '15 at 17:11
  • @rray I am using MariaDB 5.5.45 I think :-| – ReynierPM Sep 23 '15 at 17:12
  • 1
    It can be done with PDO. Here is some old code I used to answer another question with... [PDO db connection to different mysql databases : TestMysql and Rags1](http://pastebin.com/ndqmDCRt) – Ryan Vincent Sep 23 '15 at 17:22
  • @RyanVincent take a look to my edit, it's not working for me – ReynierPM Sep 23 '15 at 20:20
  • 1
    possible duplicate of [Select columns across different databases](http://stackoverflow.com/questions/674115/select-columns-across-different-databases) – Mike Sep 23 '15 at 20:34
  • @Mike this is not a dupe, I am asking how to achieve this from PDO and/or PHP not from MySQL – ReynierPM Sep 23 '15 at 20:35
  • @ReynierPM What type of database is it then? – Mike Sep 23 '15 at 20:36
  • @Mike Pls read the comments, I answer that earlier but .... *I am using MariaDB 5.5.45 I think* – ReynierPM Sep 23 '15 at 20:37
  • @ReynierPM I added the mariadb tag. Anyway, MariaDB 5.5 should be completely compatible with MySQL 5.5. The syntax you need is `databasename.tablename.columnname`. You are only doing `tablename.columnname`. – Mike Sep 23 '15 at 20:38
  • @ReynierPM Hmm ok I think I misread your question. It doesn't make sense to me that a query would work when you execute it by the command line but not by PDO. All PDO does is connect to the underlying database and send exactly the same query. Stupid question, but are you connecting using the same credentials? Also are you absolutely positively sure that `pdone_legacy.session_brand_presentation` actually does exist and there are no spelling mistakes? – Mike Sep 23 '15 at 20:50
  • @Mike, yes I am using exactly the same credentials and yes I am pretty sure that database and tables both exists, as I said I was able to execute the query using MySQL Workbench. Take a look to [this image](http://content.screencast.com/users/ReynierPM/folders/Snagit/media/d141f5dd-acf2-480d-9ec4-d3a1357f9337/09.23.2015-16.22.png) – ReynierPM Sep 23 '15 at 20:54
  • Try using aliases to see if that makes a difference (source: http://stackoverflow.com/a/2045916/811240) – Mike Sep 23 '15 at 21:03
  • @Mike no, didn't work either. See the main post I have added the SQL using aliases – ReynierPM Sep 23 '15 at 21:43
  • @Mike, yes, exactly the same message – ReynierPM Sep 23 '15 at 21:47
  • @Mike, RyanVincent, rray and anyone else pls take a look to the 3rd update at OP, was my bad all the time since I was connecting to the bad server guys, this simple issue was killing me and killing you for sure, many thx – ReynierPM Sep 24 '15 at 00:03
  • I have updated the [Pastebin - PDO use two databases](http://pastebin.com/ndqmDCRt) to use your table definitions and query! It works fine. – Ryan Vincent Sep 24 '15 at 01:31

2 Answers2

1

Here is the code to join from two separate mysql databases using PDO.

Pastebin: Tested code

Limitations:

  • Both mysql databases must be on the same server
  • Only one connection is used.
  • The database user must have the necessary privileges on both databases

Query using archive_pfizer (logger) and pdone_legacy (session_brand_presentation)

$sqlBoth = 'SELECT DISTINCT
                logger.hcp_id,
                logger.rep_id,
                logger.type,
                session_brand_presentation.ID,
                session_brand_presentation.brand_id,
                session_brand_presentation.createdAt,
                session_brand_presentation.modifiedAt
            FROM
                archive_pfizer.logger
            JOIN
                pdone_legacy.session_brand_presentation
                   ON logger.session_id = session_brand_presentation.local_session_id

            WHERE
                logger.type = :lg_type';

$stmt = $dbTest->prepare($sqlBoth);
$stmt->bindValue(':lg_type', 'email_sent', PDO::PARAM_STR);
$stmt->execute();

$resultBoth = $stmt->fetchAll();
$stmt->closeCursor();

Output:

pdone_legacy and archive_pfizer

Array
(
    [0] => Array
        (
            [hcp_id] => hcp_id_01
            [rep_id] => rep_od_01
            [type] => email_sent
            [ID] => ID_01
            [brand_id] => brand_id_01
            [createdAt] => 2015-09-24 01:42:51
            [modifiedAt] => 
        )
)

Database Connection:

/**
 * must have access rights to both db's
 */
// db connection to archive_pfizer and pdone_legacy
$dsn = 'mysql:host=localhost;dbname=pdone_legacy';
$username = 'pfizer';
$password = 'pfizer';
$options = array(
    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
$dbTest = new PDO($dsn, $username, $password, $options);
$dbTest->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Test that we can access the separate databases...

1) archive_pfizer (logger)

/* ----------------------------------------------------------
 *   Query archive_pfizer (logger)
 */
$sqlArchive = 'SELECT  hcp_id, rep_id, type, session_id, createdAt, modifiedAt
FROM archive_pfizer.logger
WHERE session_id = :a_session_id';

$stmt = $dbTest->prepare($sqlArchive);
$stmt->bindValue(':a_session_id', 'session_id_01', PDO::PARAM_STR);
$stmt->execute();

$resultArchive = $stmt->fetchAll();
$stmt->closeCursor();

echo '<br />', 'archive_pfizer.logger', '<br />';
echo '<pre>';
print_r($resultArchive);
echo '</pre>';

2) pdone_legacy (session_brand_presentation)

/* --------------------------------------------------
 *  Query pdone_legacy (session_brand_presentation)
 */
$sqlPDone = 'SELECT ID,
                    local_session_id,
                    brand_id,
                    createdAt,
                    modifiedAt
FROM pdone_legacy.session_brand_presentation
WHERE local_session_id = :sbp_session_id';

$stmt = $dbTest->prepare($sqlPDone);
$stmt->bindValue(':sbp_session_id', 'session_id_01', PDO::PARAM_STR);
$stmt->execute();

$resultPDone = $stmt->fetchAll();
$stmt->closeCursor();
echo '<br />', 'pdone_legacy.session_brand_presentation', '<br />';
echo '<pre>';
print_r($resultPDone);
echo '</pre>';
Ryan Vincent
  • 4,483
  • 7
  • 22
  • 31
0

You won't be able to do it directly with PDO. PDO is just an abstraction for your database connection.

If one of your two databases is a PostgreSQL one you could setup a Foreign Data Wrapper. With MySQL you should check the Federated storage engine.

Arkh
  • 8,416
  • 40
  • 45