Drupal 7 透過 $db_url 陣列支援多資料庫連接。本文詳細說明配置方法、動態切換、常見錯誤排查、跨庫操作技巧與 db_prefix 共用資料表策略。
在 settings.php 中將 $db_url 設為陣列:
$databases = array(
'default' => array(
'default' => array(
'database' => 'drupal_main',
'username' => 'user1',
'password' => 'pass1',
'host' => 'localhost',
'driver' => 'mysql',
'prefix' => '',
),
),
'mydb' => array(
'default' => array(
'database' => 'another_db',
'username' => 'user2',
'password' => 'pass2',
'host' => 'localhost',
'driver' => 'mysql',
'prefix' => '',
),
),
'db3' => array(
'default' => array(
'database' => 'yet_another_db',
'username' => 'user3',
'password' => 'pass3',
'host' => 'localhost',
'driver' => 'pgsql', // 支援不同驅動
'prefix' => '',
),
),
);
<?php
// 切換到 mydb 連接
db_set_active('mydb');
// 執行查詢(使用 Drupal 資料庫 API)
$results = db_query("SELECT * FROM {external_table}")->fetchAll();
// 重要:操作完成後必須切回預設連接
db_set_active('default');
| 錯誤現象 | 原因 | 解決 |
|---|---|---|
| SQL 語法錯誤 | 目標資料庫結構不同 | 檢查 SQL 相容性、欄位名稱、資料型別 |
| 找不到資料表 | 連接切換錯誤(交叉連接) | 檢查 db_set_active() 配對呼叫,確保在正確連接下執行 SQL |
| 資料寫入錯誤庫 | 忘記切回 default | 使用 try-finally 確保切回 |
| 前綴不生效 | 未使用 {table} 語法 | 查詢中資料表名用大括號包裹:{users} |
function queryExternalDb($sql, $args = [], $key = 'mydb') {
$original = db_set_active($key);
try {
return db_query($sql, $args);
} finally {
db_set_active($original); // 確保恢復原連接
}
}
// 使用
$results = queryExternalDb("SELECT * FROM {logs} WHERE type = :type", [':type' => 'error']);
當多個 Drupal 站點需共用用戶、Session、角色等資料時,可用 $db_prefix 將特定資料表指向共用資料庫:
$databases['default']['default']['prefix'] = array(
'default' => '', // 預設無前綴
'users' => 'shared_db.', // users 表指向 shared_db 資料庫
'sessions' => 'shared_db.',
'role' => 'shared_db.',
'users_roles' => 'shared_db.',
'authmap' => 'shared_db.',
'profile_fields' => 'shared_db.',
'profile_values' => 'shared_db.',
);
效果:所有站點操作 {users} 時實際操作 shared_db.users,實現單點登入 (SSO) 基礎。
// 直接在 SQL 中指定資料庫
db_query("SELECT uid FROM external_db.some_table WHERE name = :name", [':name' => $name]);
// 結合 db_set_active 使用
db_set_active('external');
db_query("SELECT * FROM {local_table}"); // 這裡的 {local_table} 會加上 external 連接的 prefix
db_set_active('default');
function mymodule_custom_query() {
global $databases; // 必須宣告 global
// 動態添加連接配置
$databases['temp_logs'] = array(
'default' => array(
'database' => 'logs_db',
'username' => 'log_user',
'password' => 'log_pass',
'host' => 'log_host',
'driver' => 'mysql',
),
);
db_set_active('temp_logs');
// 執行查詢...
db_set_active('default');
}
{table} 語法 讓 prefix 自動生效