MySQL получает все затронутые строки для нескольких операторов в одном запросе - PullRequest
0 голосов
/ 12 ноября 2010

MySQL / PHP:

Для запроса с несколькими операторами, который удаляет строки в четырех разных таблицах, я хочу узнать общее число затронутых строк.В руководстве по PHP написано, что я получу только результат последней «операции», что говорит о том, что он скажет только, сколько строк затронуло последнее из операторов DELETE.Как обойти это?

$deleteContactSQL = "DELETE FROM `persons` WHERE `persons`.`id` = '$person' AND `owner = '$user' AND `userOrContact` = 'contact';
             DELETE FROM `tabs` WHERE `person` = '$person' AND `ownerIdentity` = '$user' AND `selfOrOther` = 'other';
             DELETE FROM `tabAccess` WHERE `person`= '$person' AND `givenToIdentity` = '$user';
             DELETE FROM `personAccess` WHERE `viewedPerson` = '$person' AND `viewerIdentity` = '$user';
             ;";
include $_SERVER['DOCUMENT_ROOT'].'/goalview/includes/db.inc.php';
$deleteContacts = mysqli_query($link, $deleteContactSQL);
$success = mysqli_affected_rows($link);

Ответы [ 3 ]

1 голос
/ 14 марта 2014

Вот компактное решение mysqli_multi_query () в процедурном стиле для подсчета объединенных затронутых строк:

$deleteContactSQL="DELETE FROM `persons` WHERE `id`='$person' AND `owner='$user' AND `userOrContact`='contact';
         DELETE FROM `tabs` WHERE `person`='$person' AND `ownerIdentity`='$user' AND `selfOrOther`='other';
         DELETE FROM `tabAccess` WHERE `person`='$person' AND `givenToIdentity`='$user';
         DELETE FROM `personAccess` WHERE `viewedPerson`='$person' AND `viewerIdentity`='$user';";
include $_SERVER['DOCUMENT_ROOT'].'/goalview/includes/db.inc.php';
if(mysqli_multi_query($link,$deleteContactSQL)){
    do{
        $success+=mysqli_affected_rows($link);
    }while(mysqli_more_results($link) && mysqli_next_result($link));
}

Кроме того, эта группа запросов может быть хорошим кандидатом для некоторых TRIGGER в таблице persons.

1 голос
/ 12 ноября 2010

Что-то вроде этого может быть?

include $_SERVER['DOCUMENT_ROOT'] . '/goalview/includes/db.inc.php';

$sql = array();
$sql[] = "DELETE FROM `persons` WHERE `persons`.`id` = '$person' AND `owner = '$user' AND `userOrContact` = 'contact';"
$sql[] = "DELETE FROM `tabs` WHERE `person` = '$person' AND `ownerIdentity` = '$user' AND `selfOrOther` = 'other';"
$sql[] = "DELETE FROM `tabAccess` WHERE `person`= '$person' AND `givenToIdentity` = '$user';"
$sql[] = "DELETE FROM `personAccess` WHERE `viewedPerson` = '$person' AND `viewerIdentity` = '$user';"

$aff_rows = 0;

foreach($sql as $current_sql)
{
 $deleteContacts = mysqli_query($link, $current_sql); 
 $aff_rows = $aff_rows + mysqli_affected_rows($link);
}
0 голосов
/ 12 ноября 2010

Я бы так делал, но я бы хотел упростить вещи, которые не все могут оценить;)

$deleteContactSQL = sprintf("call cascade_delete_persons(%d,%d)", $person, $user);
$deleteContacts = mysqli_query($link, $deleteContactSQL);

drop procedure if exists cascade_delete_persons;

delimiter #

create procedure cascade_delete_persons
(
in p_pid int unsigned,
in p_oid int unsigned
)
begin

declare v_persons_count int unsigned default 0;
declare v_tabs_count int unsigned default 0;

    delete from persons where id = p_pid and owner = p_oid and userOrContact = 'contact';
    set v_persons_count = row_count();

    delete from tabs where person = p_pid and ownerIdentity = p_oid and selfOrOther = 'other';
    set v_tabs_count = row_count();

    -- etc...

    select v_persons_count as person_count, v_tabs_count as tabs_count;

end #

delimiter ;

Вы также можете использовать этот метод, если вам необходимо: http://php.net/manual/en/mysqli.multi-query.php

...