2014-12-11 2 views
2

Некоторое время я использовал несколько SQL-соединений в php, чтобы избежать «Вы не можете запускать эту команду сейчас. Команды не синхронизированы» -error.Несколько SQL-объектов в PHP/MySQLi

Кажется, что я не могу понять, когда могу делать только одно соединение, и когда мне нужно несколько. Следующий код - это то, как я извлекаю вещи из разных таблиц, связанных друг с другом.

$sql s - объекты mysqli по умолчанию, подключенные к одной базе данных. Пример - это проблема с нумерованной версией проблемы и не имеет реальной цели, если вам интересно.

$stmt1 = $sql1->prepare ('SELECT orderid,date FROM orders'); 
$stmt2 = $sql2->prepare ('SELECT product,price FROM orderlines WHERE orderid= ?'); 

$stmt1->execute(); 
$stmt1->bind_result($orderid,$date); 

while ($stmt1->fetch()) { 

echo "Order ID: " . $orderid . " from date: " . $date . ":<br>"; 

$stmt2->bind_param("i",$orderid); 
$stmt2->execute(); 
$stmt2->bind_result($product, $price); 

while ($stmt2->fetch() { 
    echo "Product from order is: " . $product . " and costs " . $price . "<br>"; 
} 

echo "End of order " . $orderid; 

} 

$stmt1->close(); 
$stmt2->close(); 

$sql1->close(); 
$sql2->close(); 

Это работает, но только если я не использую тот же объект mysqli. Если я попытаюсь сделать оба только с одним общим объективом $sql, результаты со второго stmt останутся пустыми.

Итак, вопрос: должно ли это случиться, и является ли вышеупомянутый подход хорошей или плохой практикой?

У меня нет проблем с этим - все работает очень хорошо, но способ, которым это делается, кажется мне странным, и я не могу найти ничего об этой конкретной проблеме.

EDIT: Обновлен вопрос к примеру с заказами и порядковыми номерами, чтобы отобразить, где это произойдет.

EDIT 2: I Найдено two mysqli querys, one in a while loop - но это сообщение мой вопрос как решение.

+2

Правильный подход: использование 'JOIN' из таблицы' orders' и 'orderlines' –

+0

Ну, вступив в таблицу не очень измените, как это закончится, это приведет к тому, что запрос будет выполняться медленнее, поскольку мне все еще нужен список заказов (первый оператор может иметь предложение WHERE), а затем для каждого из этих заказов мне нужно получить что-то совсем другое. Исправьте меня, если я ошибаюсь с примером. – nickdnk

+0

Что вы подразумеваете под «получить что-то совсем другое»? Пока обе таблицы могут быть связаны в соединении, вы просто указываете поля, которые вы хотите использовать, даже если они не являются ключевыми полями. – T9b

ответ

0

В одном соединении MySQL вы можете работать только с одним запросом в то время. Вы можете подготовить еще несколько инструкций сразу (эти данные все еще хранятся в драйвере MySQLi), однако, как только вы используете execute(), оператор будет отправлен в базу данных, и в базе данных ожидается, что все будущие запросы bind_param() и bind_result() будут иметь это же заявление, пока вы не отправите новый оператор.

Два оператора в то же время => два соединения с DB => двумя объектами mysqli.


Plus ваша проблема может быть решена в одном запросе, как:

$stmt1 = $sql1->prepare ('SELECT o.orderid,o.date,b.product,b.price FROM orders o LEFT JOIN orderlines b ON b.orderid=o.orderid ORDER BY o.orderid'); 
$stmt1->execute(); 
$stmt1->bind_result($orderid,$date,$product,$price); 
$prev_order_id=false; 
while ($stmt1->fetch()) 
{ 
    if($prev_order_id!=$orderid) 
    { 
     if($prev_order_id!==false) 
      echo "End of order " . $prev_orderid."<br>"; 
     echo "Order ID: " . $orderid . " from date: " . $date . ":<br>"; 
    } 
    if(is_null($product)) 
     echo "Product from order is: " . $product . " and costs " . $price . "<br>"; 
    $prev_order_id=$orderid; 
} 
if($prev_order_id!==false) 
    echo "End of order " . $prev_orderid."<br>"; 
$stmt1->close(); 
$sql1->close(); 
+0

Это хорошо. Знаете ли вы, что использование нескольких соединений SQL считается плохой практикой? – nickdnk

+0

@nickdnk: зависит от вашей проблемы. Если вам это нужно, сделайте это. Решать «проблему», используя большее количество соединений с простым алгоритмом или использовать только одно соединение с использованием сложного алгоритма, очень ситуативно. Лучшей практикой было бы проверить оба варианта и выбрать лучшее. – David162795

+0

Спасибо. Меня беспокоит то, что происходит, когда вы используете несколько объектов SQL и как это влияет на использование ЦП и ОЗУ для сервера, не говоря уже о том, насколько безопасно полагаться на разные соединения.У меня пока не было никаких проблем, но моя пользовательская база тоже не очень большая. С конфигурацией подключения MySQL max по умолчанию на 100 или 150 по умолчанию я не знал, пошел ли я по плохому пути. – nickdnk

Смежные вопросы