PHP - 使用 PDO 从具有不同凭据的不同数据库中的两个表进行左连接
PHP - Left join from two tables in different databases with different credentials using PDO
请注意:虽然我最初的问题无法按照我预期的方式解决,但在此 post 中标记了@Bamar 解决方案是达到相同目标并且完美运行的替代方案。如果数据库位于不同的主机上,我在此 post 中提出的建议似乎不可行。
我找了一段时间,似乎无法解决我的问题。
我拥有的数据
我的服务提供商是 1&1。在我与他们的当前合同中,我最多可以创建 100 个数据库,每个数据库的最大大小为 2GB。
创建的每个数据库都分配了一个随机的主机名、端口和用户名(我唯一可以选择的项目是密码)。
我有两个不同的数据库,我们称它们为 DB_1 和 DB_2.
在 DB_1 中,我有一个名为 T_USERS 的 table问题是:
- ID:记录的ID。
- userName:数据库注册的用户名
在 DB_2 我有一个 table 叫做 T_SCORES 哪个字段对这个特定问题感兴趣的是:
- ID_User:它是一个外键,指的是DB_1.T_USERS中特定用户的ID
- score:表示该用户得分的数值。
重要的是要考虑到要访问两个数据库,每个数据库都需要不同的凭据!
我想要达到的目标
我想要实现的目标乍一看似乎很简单,但我无法在网上找到任何关于如何使用 PHP 和 PDO 实现此目标的文档或解决方案。
我只想执行与 DB_2.ID_USER 和 DB_1.ID
的连接
我的最终结果应该是这样的:
DB_1.userName
DB_2.score
Alex
237
Peter
120
Mark
400
...
...
我目前被困在哪里
这是我目前尝试过的。
首先,我按如下方式连接到我的数据库(我通常在连接到数据库时使用 try/catch,但我会在这里省略它):
//Connection to the DB1
$db1_hostName = "hostnameofDB1";//The host name of the database 1
$db1_name = "db1";//The name of the database 1
$db1_userName = "user1";//The username in the database 1
$db1_password = "pw1";//The password for the database 1
$pdo_db1Handle = new PDO("mysql:host=$db1_hostName; dbname=$db1_name;", $db1_userName, $db1_password);
$pdo_db1Handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//Connection to the DB2
$db2_hostName = "hostnameofDB2";//The host name of the database 2
$db2_name = "db2";//The name of the database 2
$db2_userName = "user2";//The username in the database 2
$db2_password = "pw2";//The password for the database 2
$pdo_db2Handle = new PDO("mysql:host=$db2_hostName; dbname=$db2_name;", $db2_userName, $db2_password);
$pdo_db2Handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
基本上到目前为止,我所做的非常简单,创建 pdo_db1Handle 和 pdo_db2Handle。现在到了棘手的部分...
如果我现在想执行连接,我的 SQL 语法应该是这样的:
SELECT DB_1.T_USERS.userName, DB_2.T_SCORES.score
FROM DB_2.T_SCORES
LEFT JOIN DB_1.T_USERS
ON (DB_2.T_SCORES.ID_User=DB_1.T_USERS.ID)
ORDER BY DB_2.T_SCORES.score ASC 'The ordering is optional, I'm interested in the join part first
但据我所知以及我能够找到的所有信息,您对我之前按以下方式定义的两个句柄之一执行 SQL 语句:
$stmt=$pdo_db1Handle->prepare($mySQLStatement);
$stmt->execute();
当我尝试执行此操作时,出现错误提示我缺少 DB_2 的凭据。如果我尝试针对 pdo_db2Handle.
执行它,它会发生相反的情况(缺少 DB_1 的凭据)
我该如何进行?为此使用 PDO 的任何解决方案?
提前致谢:)
如果必须使用单独的 PDO 连接,则无法加入,因此请使用嵌套循环并加入 PHP 中的数据。
$stmt_user = $pdo_db1Handle->query("SELECT id, username FROM t_users");
$stmt_score = $pdo_db2Handle->prepare("SELECT score FROM t_scores WHERE id_user = :userid");
$results = [];
while ($row_user = $stmt_user->fetch(PDO::FETCH_ASSOC)) {
$scores = [];
$stmt_score->execute(':userid' => $row_user['id']);
while ($row_score = $stmt_score->fetch(PDO::FETCH_ASSOC)) {
$scores[] = $row_score['score'];
}
$results[$row_user['username']] = $scores;
}
这将创建一个关联数组,其键是用户名,值是用户分数的数组。
根据您的用例,解决方法可能是暂时 并在单个数据库中同时拥有两个 table 后执行 sql:
$pdo1 = new PDO('mysql:host=$db1_hostName; dbname=$db1_name', $db1_userName, $db1_password);
$pdo2 = new PDO('mysql:host=$db2_hostName; dbname=$db1_name', $db2_userName, $db2_password);
$insert_stmt = $pdo2->prepare("INSERT INTO T_SCORES (col1, col2, col3, ...) VALUES (:col1, :col2, :col3, ...) ON DUPLICATE KEY IGNORE");
$select_results = $pdo1->query("SELECT * FROM T_SCORES");
while ($row = $select_results->fetch(PDO::FETCH_ASSOC)) {
$insert_stmt->execute($row);
}
-- now work with the tables as you usually would.
您可以事先在目标数据库中创建 table 并在执行插入后截断 and/or 之前的数据。
请注意:虽然我最初的问题无法按照我预期的方式解决,但在此 post 中标记了@Bamar 解决方案是达到相同目标并且完美运行的替代方案。如果数据库位于不同的主机上,我在此 post 中提出的建议似乎不可行。
我找了一段时间,似乎无法解决我的问题。
我拥有的数据
我的服务提供商是 1&1。在我与他们的当前合同中,我最多可以创建 100 个数据库,每个数据库的最大大小为 2GB。
创建的每个数据库都分配了一个随机的主机名、端口和用户名(我唯一可以选择的项目是密码)。
我有两个不同的数据库,我们称它们为 DB_1 和 DB_2.
在 DB_1 中,我有一个名为 T_USERS 的 table问题是:
- ID:记录的ID。
- userName:数据库注册的用户名
在 DB_2 我有一个 table 叫做 T_SCORES 哪个字段对这个特定问题感兴趣的是:
- ID_User:它是一个外键,指的是DB_1.T_USERS中特定用户的ID
- score:表示该用户得分的数值。
重要的是要考虑到要访问两个数据库,每个数据库都需要不同的凭据!
我想要达到的目标
我想要实现的目标乍一看似乎很简单,但我无法在网上找到任何关于如何使用 PHP 和 PDO 实现此目标的文档或解决方案。
我只想执行与 DB_2.ID_USER 和 DB_1.ID
的连接
我的最终结果应该是这样的:
DB_1.userName | DB_2.score |
---|---|
Alex | 237 |
Peter | 120 |
Mark | 400 |
... | ... |
我目前被困在哪里
这是我目前尝试过的。
首先,我按如下方式连接到我的数据库(我通常在连接到数据库时使用 try/catch,但我会在这里省略它):
//Connection to the DB1
$db1_hostName = "hostnameofDB1";//The host name of the database 1
$db1_name = "db1";//The name of the database 1
$db1_userName = "user1";//The username in the database 1
$db1_password = "pw1";//The password for the database 1
$pdo_db1Handle = new PDO("mysql:host=$db1_hostName; dbname=$db1_name;", $db1_userName, $db1_password);
$pdo_db1Handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//Connection to the DB2
$db2_hostName = "hostnameofDB2";//The host name of the database 2
$db2_name = "db2";//The name of the database 2
$db2_userName = "user2";//The username in the database 2
$db2_password = "pw2";//The password for the database 2
$pdo_db2Handle = new PDO("mysql:host=$db2_hostName; dbname=$db2_name;", $db2_userName, $db2_password);
$pdo_db2Handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
基本上到目前为止,我所做的非常简单,创建 pdo_db1Handle 和 pdo_db2Handle。现在到了棘手的部分...
如果我现在想执行连接,我的 SQL 语法应该是这样的:
SELECT DB_1.T_USERS.userName, DB_2.T_SCORES.score
FROM DB_2.T_SCORES
LEFT JOIN DB_1.T_USERS
ON (DB_2.T_SCORES.ID_User=DB_1.T_USERS.ID)
ORDER BY DB_2.T_SCORES.score ASC 'The ordering is optional, I'm interested in the join part first
但据我所知以及我能够找到的所有信息,您对我之前按以下方式定义的两个句柄之一执行 SQL 语句:
$stmt=$pdo_db1Handle->prepare($mySQLStatement);
$stmt->execute();
当我尝试执行此操作时,出现错误提示我缺少 DB_2 的凭据。如果我尝试针对 pdo_db2Handle.
执行它,它会发生相反的情况(缺少 DB_1 的凭据)
我该如何进行?为此使用 PDO 的任何解决方案?
提前致谢:)
如果必须使用单独的 PDO 连接,则无法加入,因此请使用嵌套循环并加入 PHP 中的数据。
$stmt_user = $pdo_db1Handle->query("SELECT id, username FROM t_users");
$stmt_score = $pdo_db2Handle->prepare("SELECT score FROM t_scores WHERE id_user = :userid");
$results = [];
while ($row_user = $stmt_user->fetch(PDO::FETCH_ASSOC)) {
$scores = [];
$stmt_score->execute(':userid' => $row_user['id']);
while ($row_score = $stmt_score->fetch(PDO::FETCH_ASSOC)) {
$scores[] = $row_score['score'];
}
$results[$row_user['username']] = $scores;
}
这将创建一个关联数组,其键是用户名,值是用户分数的数组。
根据您的用例,解决方法可能是暂时
$pdo1 = new PDO('mysql:host=$db1_hostName; dbname=$db1_name', $db1_userName, $db1_password);
$pdo2 = new PDO('mysql:host=$db2_hostName; dbname=$db1_name', $db2_userName, $db2_password);
$insert_stmt = $pdo2->prepare("INSERT INTO T_SCORES (col1, col2, col3, ...) VALUES (:col1, :col2, :col3, ...) ON DUPLICATE KEY IGNORE");
$select_results = $pdo1->query("SELECT * FROM T_SCORES");
while ($row = $select_results->fetch(PDO::FETCH_ASSOC)) {
$insert_stmt->execute($row);
}
-- now work with the tables as you usually would.
您可以事先在目标数据库中创建 table 并在执行插入后截断 and/or 之前的数据。