同一个查询涉及两个数据库时如何执行PDO语句?
How to execute PDO statement when there are two databases involve in the same query?
我需要执行此 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';
您可能已经注意到我正在查询不同的数据库:archive_pfizer
和 pdone_legacy
。我知道 DSN 需要一个数据库名称来创建 PDO object 然后如标题所述:当有两个数据库涉及同一查询时,我如何执行 PDO 语句?
非常重要 我问如何使用 PDO 从 PHP 实现这一点,我能够从 MySQL/MariaDB 命令行成功执行查询 and/or 使用任何 GUI。
更新
这是我基于 @RyanVincent 回答的代码:
$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;
}
但是我得到了这个错误:
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'
显然,当它是数据库时,它将 pdone_legacy.session_brand_presentation
作为 table,在提供的示例中与 testmysql
相同,有什么建议吗?
更新 2
尝试相同的 SQL 查询但使用别名也不起作用:
$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"';
遇到与之前完全相同的问题。
更新 3
好吧,也许我说完之后会被杀,但一直都是我的错。我正在连接到存在 DB pdone_legacy
的服务器,但实际上该 DB 没有 session_brand_presentation
table,这就是 PDO 一直在说的。无论如何,感谢这里的任何人,两个查询都有效。
您将无法直接使用 PDO 执行此操作。 PDO 只是您的数据库连接的抽象。
如果您的两个数据库之一是 PostgreSQL,您可以设置 Foreign Data Wrapper. With MySQL you should check the Federated storage engine。
这是使用 PDO 从两个单独的 mysql 数据库加入的代码。
限制:
- 两个 mysql 数据库必须在同一台服务器上
- 只使用了一个连接。
- 数据库用户必须对两个数据库都具有必要的权限
使用 archive_pfizer(记录器)和 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();
输出:
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] =>
)
)
数据库连接:
/**
* 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);
测试我们是否可以访问单独的数据库...
1) archive_pfizer(记录器)
/* ----------------------------------------------------------
* 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>';
我需要执行此 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';
您可能已经注意到我正在查询不同的数据库:archive_pfizer
和 pdone_legacy
。我知道 DSN 需要一个数据库名称来创建 PDO object 然后如标题所述:当有两个数据库涉及同一查询时,我如何执行 PDO 语句?
非常重要 我问如何使用 PDO 从 PHP 实现这一点,我能够从 MySQL/MariaDB 命令行成功执行查询 and/or 使用任何 GUI。
更新
这是我基于 @RyanVincent 回答的代码:
$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;
}
但是我得到了这个错误:
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'
显然,当它是数据库时,它将 pdone_legacy.session_brand_presentation
作为 table,在提供的示例中与 testmysql
相同,有什么建议吗?
更新 2
尝试相同的 SQL 查询但使用别名也不起作用:
$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"';
遇到与之前完全相同的问题。
更新 3
好吧,也许我说完之后会被杀,但一直都是我的错。我正在连接到存在 DB pdone_legacy
的服务器,但实际上该 DB 没有 session_brand_presentation
table,这就是 PDO 一直在说的。无论如何,感谢这里的任何人,两个查询都有效。
您将无法直接使用 PDO 执行此操作。 PDO 只是您的数据库连接的抽象。
如果您的两个数据库之一是 PostgreSQL,您可以设置 Foreign Data Wrapper. With MySQL you should check the Federated storage engine。
这是使用 PDO 从两个单独的 mysql 数据库加入的代码。
限制:
- 两个 mysql 数据库必须在同一台服务器上
- 只使用了一个连接。
- 数据库用户必须对两个数据库都具有必要的权限
使用 archive_pfizer(记录器)和 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();
输出:
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] =>
)
)
数据库连接:
/**
* 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);
测试我们是否可以访问单独的数据库...
1) archive_pfizer(记录器)
/* ----------------------------------------------------------
* 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>';