【发布时间】:2014-10-18 19:57:56
【问题描述】:
当$comp_ids 存在于第二个查询中时,脚本可以正常工作...如果它不存在,则脚本会失败。
我在这里唯一的猜测是,因为我正在使用交易,它忽略了我在第二个查询中的条件 - if( count($comp_ids) > 0 )... 是这样吗?如果是这样,我怎样才能在保持交易功能的同时解决这个问题?我只想在它们都成功的情况下执行这两个查询......或者在这种情况下......第一个成功,因为第二个不应该由于条件而发生。
有什么想法吗?
//find account based off subscription reference
$stmt = $db->prepare("
SELECT
accounts.account_id,
accounts.licenses,
GROUP_CONCAT(computers.computer_id ORDER BY computers.computer_id ASC) AS comp_ids
FROM accounts
LEFT JOIN computers
ON computers.account_id = accounts.account_id
WHERE accounts.subscription = :subscription
");
$stmt->bindValue(':subscription', $_POST['SubscriptionReference']);
$stmt->execute();
//result (can only be one or none)
$result = $stmt->fetch(PDO::FETCH_ASSOC);
// if account exists and it is not a test then update it
//if ($result && $_POST['SubscriptionIsTest'] != 'true')
if ($result)
{
//inserting into two different tables so use a transaction (if either fails both fail)
try {
// begin transaction
$db->beginTransaction();
// accounts update
$stmt = $db->prepare("
UPDATE accounts
SET account_email = :account_email,
licenses = :licenses,
fname = :fname,
lname = :lname,
subscription = :subscription,
subscription_url = :subscription_url,
dtEnd = :dtEnd,
dtNextPeriod = :dtNextPeriod
WHERE account_id = :account_id
");
//bindings
$binding = array(
'account_email' => $_POST['email'],
'licenses' => $_POST['SubscriptionQuantity'],
'fname' => $_POST['firstName'],
'lname' => $_POST['lastName'],
'subscription' => $_POST['SubscriptionReference'],
'subscription_url' => $_POST['SubscriptionCustomerUrl'],
'dtEnd' => strtotime($_POST['SubscriptionEndDate']),
'dtNextPeriod' => strtotime($_POST['SubscriptionNextPeriodDate']),
'account_id' => $result['account_id']
);
$stmt->execute($binding);
// update computers status because license count changed
// get comp_ids array
$comp_ids = explode(',', $result['comp_ids']);
//if there are any comp_ids then...
if( count($comp_ids) > 0 )
{
//build in clause & binding using selected array
$prefix = $in_clause = '';
$binding_clause = array();
foreach($comp_ids as $key=>$value)
{
$in_clause .= $prefix.':selected_'.$key;
$prefix = ', ';
$binding_clause[':selected_'.$key] = $value;
}
//set counter for loop
$counter = 0;
//zero the string
$update_cond = '';
//create the case conditions
foreach($comp_ids as $key)
{
$comp_status = $counter < $result['licenses'] ? 1 : 0;
$update_cond .= "WHEN ".$key." THEN ".$comp_status."\n";
//inc counter
$counter++;
}
//since there are comps then update their status
$stmt = $db->prepare("
UPDATE computers SET
status = CASE computer_id
".$update_cond."
ELSE status
END
WHERE computer_id IN(". $in_clause .")
");
//execute the changes
$stmt->execute($binding_clause);
}
// if we arrive here, it means that no exception was thrown
// i.e. no query has failed, and we can commit the transaction
$db->commit();
}
catch(Exception $e)
{
//error message
error_log('/fastspring/spc/sub_changed.php: ' .$e->getMessage());
// roll back the db changes if any
$db->rollback();
//failed - send myself an email about this
}
}
//account does not exist so do something to handle the error
else
{
//failed - send myself an email about this
}
错误...抱歉,忘记添加了:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'THEN 1
ELSE status
END
WHERE computer_id IN(?)' at line 3
【问题讨论】:
-
失败怎么办? php错误?数据库错误?宇宙遭受了彻底的存在失败?
-
对不起,完全以为我已经添加了,但一定忘记了。已更新。
标签: php mysql pdo transactions