Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute PDO statement when there are two databases involve in the same query?

Tags:

php

pdo

mariadb

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.

like image 617
ReynierPM Avatar asked May 26 '26 09:05

ReynierPM


1 Answers

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>';
like image 194
Ryan Vincent Avatar answered May 27 '26 21:05

Ryan Vincent



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!