Como você se conecta a vários bancos de dados MySQL em uma única página?

179

Eu tenho informações espalhadas por alguns bancos de dados e quero colocar todas as informações em uma página da Web usando PHP. Eu queria saber como posso conectar a vários bancos de dados em uma única página PHP.

Eu sei como me conectar a um único banco de dados usando:

$dbh = mysql_connect($hostname, $username, $password) 
        or die("Unable to connect to MySQL");

No entanto, posso apenas usar vários comandos "mysql_connect" para abrir os outros bancos de dados e como o PHP saberia de qual banco de dados eu quero que as informações sejam extraídas se eu tiver vários bancos de dados conectados.

JoshFinnie
fonte

Respostas:

335

Aviso: as mysql_xx funções estão obsoletas desde o php 5.5 e removidas desde o php 7.0 (consulte http://php.net/manual/intro.mysql.php ), use mysqli_xxfunções ou veja a resposta abaixo em @Troelskn


Você pode fazer várias chamadas para mysql_connect(), mas se os parâmetros forem os mesmos, será necessário passar true para o $new_linkparâmetro ' ' (quarto), caso contrário, a mesma conexão será reutilizada. Por exemplo:

$dbh1 = mysql_connect($hostname, $username, $password); 
$dbh2 = mysql_connect($hostname, $username, $password, true); 

mysql_select_db('database1', $dbh1);
mysql_select_db('database2', $dbh2);

Em seguida, para consultar o banco de dados 1, passe o primeiro identificador de link:

mysql_query('select * from tablename', $dbh1);

e para o banco de dados 2, passe o segundo:

mysql_query('select * from tablename', $dbh2);

Se você não passar um identificador de link, a última conexão criada será usada (nesse caso, a representada por $dbh2), por exemplo:

mysql_query('select * from tablename');

Outras opções

Se o usuário do MySQL tiver acesso aos dois bancos de dados e eles estiverem no mesmo host (ou seja, os dois bancos de dados estiverem acessíveis na mesma conexão), você poderá:

  • Mantenha uma conexão aberta e chame mysql_select_db()para alternar entre conforme necessário. Não tenho certeza se esta é uma solução limpa e você pode acabar consultando o banco de dados errado.
  • Especifique o nome do banco de dados ao fazer referência a tabelas nas suas consultas (por exemplo SELECT * FROM database2.tablename). É provável que seja uma dor de implementar.

Leia também a resposta do troelskn, porque essa é uma abordagem melhor se você puder usar o DOP em vez das extensões mais antigas.

Tom Haigh
fonte
2
+1 Esta solução funcionou para mim. Após dois dias de depuração por que meus modelos WordPress personalizados estavam perdendo acesso ao objeto $ WP_Query após uma chamada para a segunda conexão com o banco ...
Eddie B
é possível definir um deles para o padrão e ter que adicionar $dbh2o segundo apenas quando necessário? Ter que mudar todas as consultas para esta abordagem ao trabalho provavelmente levaria dias apenas encontrar todos eles ...
thomask
@ThomasK, você poderia envolver mysql_query em uma função com um parâmetro padrão, dizem, db_query($query,$db='db1')e depois atualizar em massa todas as suas consultas de idade para db_query($query)seguido por costume atualizar seus entes não-padrão paradb_query($query,'db2')
joshuahedlund
Usando seu método, qual conexão será usada se eu definir duas conexões, mas não especificar qual conexão usar na consulta?
Pedro #
1
@ Pedro: de acordo com php.net/manual/en/function.mysql-query.php :If the link identifier is not specified, the last link opened by mysql_connect() is assumed.
Tom Haigh
97

Se você usa o PHP5 (e deve, já que o PHP4 foi descontinuado), você deve usar o DOP , pois este está lentamente se tornando o novo padrão. Um benefício (muito) importante do PDO é que ele suporta parâmetros vinculados, o que contribui para um código muito mais seguro.

Você se conectaria através do DOP, assim:

try {
  $db = new PDO('mysql:dbname=databasename;host=127.0.0.1', 'username', 'password');
} catch (PDOException $ex) {
  echo 'Connection failed: ' . $ex->getMessage();
}

(Obviamente, substitua nome do banco de dados, nome de usuário e senha acima)

Você pode consultar o banco de dados da seguinte maneira:

$result = $db->query("select * from tablename");
foreach ($result as $row) {
  echo $row['foo'] . "\n";
}

Ou, se você tiver variáveis:

$stmt = $db->prepare("select * from tablename where id = :id");
$stmt->execute(array(':id' => 42));
$row = $stmt->fetch();

Se você precisar de várias conexões abertas ao mesmo tempo, basta criar várias instâncias do PDO:

try {
  $db1 = new PDO('mysql:dbname=databas1;host=127.0.0.1', 'username', 'password');
  $db2 = new PDO('mysql:dbname=databas2;host=127.0.0.1', 'username', 'password');
} catch (PDOException $ex) {
  echo 'Connection failed: ' . $ex->getMessage();
}
Troelskn
fonte
5
Por que essa resposta não está no topo ?! Esta é a maneira correta de fazer isso.
Aditya MP
10
@ aditya menon na minha opinião, a maneira certa de fazer algo com frequência não é a resposta certa para a pergunta em questão. o Asker não estava usando o DOP em sua pergunta, mas as funções nativas do php mysql, então acredito que a resposta mais adequada seguiria o código do asker.
Jonathan dos Santos
2
@adityamenon sob a autoridade de quem? Lembre-se de que o usuário está sempre certo ... A DOP é a melhor maneira, mas ambas as maneiras são a maneira certa de resolver o problema do usuário. Observe a diferença entre o certo e o melhor. Sim ... Estou entediado, então tive que fazer uma declaração.
JustinKaz
$ Db1 e $ db2 representam várias conexões mysql? Se assim for, isso não é bom. Existe alguma maneira de acomodar vários bancos de dados com apenas uma conexão?
Datasn.io
@kavoir Por que você quer isso? Se necessário, você pode alterar o banco de dados na conexão atual com use DATABASENAME, mas não vejo o ponto?
troelskn
9

Acabei de simplificar minha vida:

CREATE VIEW another_table AS SELECT * FROM another_database.another_table;

espero que seja útil ... felicidades ...

Ihsan Kusasi
fonte
1
Essa é a solução mais fácil se você não tiver tabelas com o mesmo nome nos dois bancos de dados. Você faz isso uma vez e não precisa mais se preocupar com vários bancos de dados.
Erel Segal-Halevi
@ ErelSegal-Halevi, desde que você precise apenas de acesso somente leitura aos dados do outro banco de dados, certo?
Buttle Butkus
6

Em vez de mysql_connect, use mysqli_connect .

O mysqli é uma funcionalidade para conectar vários bancos de dados ao mesmo tempo.

$Db1 = new mysqli($hostname,$username,$password,$db_name1); 
// this is connection 1 for DB 1

$Db2 = new mysqli($hostname,$username,$password,$db_name2); 
// this is connection 2 for DB 2
Kaushik
fonte
1
$ hostname = 'Seu DB_Hostname'; $ username = 'Seu DB_Username'; $ password = 'sua senha_do_BD'; $ db_name1 = 'seu nome_BD_1'; $ db_name2 = 'Seu DB_Name 2';
kaushik
É errado que isso não funcione #mysql_connect
Nico Haase
4

Experimente o código abaixo:

    $conn = mysql_connect("hostname","username","password");
    mysql_select_db("db1",$conn);
    mysql_select_db("db2",$conn);

    $query1 = "SELECT * FROM db1.table";
    $query2 = "SELECT * FROM db2.table";

Você pode buscar dados da consulta acima do banco de dados como abaixo

$rs = mysql_query($query1);
while($row = mysql_fetch_assoc($rs)) {
    $data1[] = $row;
}

$rs = mysql_query($query2);
while($row = mysql_fetch_assoc($rs)) {
    $data2[] = $row;
}

print_r($data1);
print_r($data2);
Paks
fonte
Os dadas duas consultas iria funcionar da mesma maneira sem chamar mysql_select_dbsequer uma vez - também, chamando-o duas vezes sem qualquer outra coisa no meio é inútil
Nico Haase
4
$dbh1 = mysql_connect($hostname, $username, $password);  
$dbh2 = mysql_connect($hostname, $username, $password, true); 

mysql_select_db('database1', $dbh1); 
mysql_select_db('database2',$dbh2); 

mysql_query('select * from tablename', $dbh1);
mysql_query('select * from tablename', $dbh2);

Esta é a solução mais óbvia que eu uso, mas lembre-se, se o nome de usuário / senha para o banco de dados for exatamente o mesmo no mesmo host, essa solução sempre estará usando a primeira conexão. Portanto, não se confunda que isso não esteja funcionando nesse caso. O que você precisa fazer é criar 2 usuários diferentes para os 2 bancos de dados e ele funcionará.

Companheiro preguiçoso
fonte
3

A menos que você realmente precise ter mais de uma instância de um objeto PDO em jogo, considere o seguinte:

$con = new PDO('mysql:host=localhost', $username, $password, 
      array(PDO::ATTR_PERSISTENT => true));

Observe a ausência de dbname=nos argumentos de construção.

Quando você se conecta ao MySQL através de um terminal ou outra ferramenta, o nome do banco de dados não é necessário imediatamente. Você pode alternar entre bancos de dados usando a USE dbnameinstrução por meio do PDO::exec()método

$con->exec("USE someDatabase");
$con->exec("USE anotherDatabase");

É claro que você pode incluir isso em uma declaração catch try.

Michael Ratcliffe
fonte
Para aqueles que tentariam a abordagem acima, dê uma olhada antes desse stackoverflow.com/a/14933070/1623579
TheFrost
Eu amo essa solução! Posso prescindir da configuração persistente, mas a instanciação do DOP é uma ótima solução. Você obtém uma conexão padrão sem estar conectado a um banco de dados específico.
Chuck Burgess
2

Você pode usar a sintaxe do MySQLi, o que permitiria lidar melhor com isso.

Defina as conexões com o banco de dados e, sempre que desejar consultar um dos bancos de dados, especifique a conexão correta.

Por exemplo:

$Db1 = new mysqli('$DB_HOST','USERNAME','PASSWORD'); // 1st database connection 
$Db2 = new mysqli('$DB_HOST','USERNAME','PASSWORD'); // 2nd database connection

Para consultá-los na mesma página, use algo como:

$query = $Db1->query("select * from tablename")
$query2 = $Db2->query("select * from tablename")
die("$Db1->error");

Mudar para o MySQLi dessa maneira irá ajudá-lo.

user3857891
fonte
Melhore sua sintaxe (isso não é um sms) e formate seu código com as ferramentas (Ctrl + K, por exemplo).
fedorqui 'Então, pare de prejudicar'
2

Você realmente não precisa select_db. Você pode enviar uma consulta para dois bancos de dados ao mesmo tempo. Em primeiro lugar, dar uma bolsa para DB1selecionar a partir DB2de GRANT select ON DB2.* TO DB1@localhost;. Então FLUSH PRIVILEGES;,. Por fim, você pode fazer uma 'consulta de banco de dados múltiplo' como SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2etc. (não se esqueça de que precisa de acesso 'root' para usar o comando grant)

Nagibaba
fonte
1

se você estiver usando o mysqli e tiver dois arquivos db_connection. como o primeiro é

define('HOST','localhost');
define('USER','user');
define('PASS','passs');
define('**DB1**','database_name1');

$connMitra = new mysqli(HOST, USER, PASS, **DB1**);

segundo é

    define('HOST','localhost');
    define('USER','user');
    define('PASS','passs');
    define(**'DB2**','database_name1');

    $connMitra = new mysqli(HOST, USER, PASS, **DB2**);

SO apenas mude o nome da passagem de parâmetro no mysqli como DB1 e DB2. se você passar o mesmo parâmetro no mysqli suponha que o DB1 nos dois arquivos, o segundo banco de dados não se conectará mais. Então lembre-se de quando você usa duas ou mais conexões, passe nomes de parâmetros diferentes na função mysqli

Kamal Bunkar
fonte
-1
<?php
    // Sapan Mohanty
    // Skype:sapan.mohannty
    //***********************************
    $oldData = mysql_connect('localhost', 'DBUSER', 'DBPASS');
    echo mysql_error();
    $NewData = mysql_connect('localhost', 'DBUSER', 'DBPASS');
    echo mysql_error();
    mysql_select_db('OLDDBNAME', $oldData );
    mysql_select_db('NEWDBNAME', $NewData );
    $getAllTablesName    = "SELECT table_name FROM information_schema.tables WHERE table_type = 'base table'";
    $getAllTablesNameExe = mysql_query($getAllTablesName);
    //echo mysql_error();
    while ($dataTableName = mysql_fetch_object($getAllTablesNameExe)) {

        $oldDataCount       = mysql_query('select count(*) as noOfRecord from ' . $dataTableName->table_name, $oldData);
        $oldDataCountResult = mysql_fetch_object($oldDataCount);


        $newDataCount       = mysql_query('select count(*) as noOfRecord from ' . $dataTableName->table_name, $NewData);
        $newDataCountResult = mysql_fetch_object($newDataCount);

        if ( $oldDataCountResult->noOfRecord != $newDataCountResult->noOfRecord ) {
            echo "<br/><b>" . $dataTableName->table_name . "</b>";
            echo " | Old: " . $oldDataCountResult->noOfRecord;
            echo " | New: " . $newDataCountResult->noOfRecord;

            if ($oldDataCountResult->noOfRecord < $newDataCountResult->noOfRecord) {
                echo " | <font color='green'>*</font>";

            } else {
                echo " | <font color='red'>*</font>";
            }

            echo "<br/>----------------------------------------";

        }     

    }
    ?>
Sapan Mohanty
fonte
Para mais informações você pode visitar github.com/sapankumarmohanty/CountRecordsAtMigrationFinalSync
htngapi