it-swarm-vi.com

Kiểm tra xem truy vấn INSERT thành công hay thất bại vì một khóa UNIITE trùng lặp

Tôi có một bảng db được gọi là league trong đó cột mail là id duy nhất:

|name |mail               |
|Bryan|[email protected]  |

Tôi có một lối vào nơi người dùng có thể đăng ký và sau đó tôi có cái này cho phụ trợ:

$db = JFactory::getDbo();
$query = $db->getQuery(true);
$jinput = JFactory::getApplication()->input;

$name = $jinput->getString('name');
$mail = $jinput->getString('mail');

$columns = array('name', 'mail');

$values = array($db->quote($name), $db->quote($mail));

$query
    ->insert($db->quoteName('league'))
    ->columns($db->quoteName($columns))
    ->values(implode(',', $values));

$db->setQuery($query);
$db->execute();

Bây giờ, nếu Bryan cố gắng đăng ký với cùng một thư, sẽ xảy ra lỗi. Làm cách nào để viết một tin nhắn thay vì trang lỗi thông thường? Tôi muốn một cái gì đó như: "Cảm ơn bạn đã đăng ký" nếu truy vấn thành công và "Bạn đã đăng ký" nếu truy vấn không thành công.

3
Daniel Jensen

Bạn sẽ cần thực hiện một truy vấn select đối với bảng cơ sở dữ liệu của bạn, tìm kiếm địa chỉ email. Nếu kết quả được trả về, bạn có thể ném một thông báo cảnh báo, người khác thực hiện truy vấn insert, đại loại như thế này:

$jinput = JFactory::getApplication()->input;
$name   = $jinput->getString('name');
$mail   = $jinput->getString('mail');

$db = JFactory::getDbo();

$query = $db->getQuery(true)
      ->select($db->quoteName('mail'))
      ->from($db->quoteName('league'))
      ->where($db->quoteName('mail') . ' = '. $db->quote($mail));
$db->setQuery($query);

$result = $db->loadResult();

if (!$result)
{
    $columns = array('name', 'mail');
    $values = array($db->quote($name), $db->quote($mail));

    $query = $db->getQuery(true);

    $query->clear();
    $query->insert($db->quoteName('league'))
        ->columns($db->quoteName($columns))
        ->values(implode(',', $values));

    $db->setQuery($query);
    $db->execute();
}
else
{
    JFactory::getApplication()->enqueueMessage('Email already exists', 'error');
}
3
Lodder

mail là một khóa bảng ĐỘC ĐÁO (PRIMARY hoạt động giống nhau), bạn có thể thực hiện logic dự định của mình chỉ bằng một truy vấn. Theo thông lệ mã hóa tốt nhất, bạn phải luôn thực hiện càng ít truy vấn càng tốt.

Như bạn sẽ thấy, không có lý do gì để gọi một truy vấn CHỌN. Nếu không có lỗi/ngoại lệ nào bị bắt, thì INSERT của bạn đã thành công. Nếu một địa chỉ email trùng lặp được gửi, thì một ngoại lệ rất nhiều thông tin sẽ được tạo ra. Bạn chỉ cần lắng nghe mã lỗi tiềm năng: 1062.

Mã số:

$jinput = JFactory::getApplication()->input;
$name = $jinput->getString('name');
$mail = $jinput->getString('mail');

if (!filter_var($mail, FILTER_VALIDATE_EMAIL)) {
    JFactory::getApplication()->enqueueMessage('Invalid Email. Please Check Email & Try Again.', 'notice');
} else {
    $db = JFactory::getDBO();
    try {
        $query = $db->getQuery(true)
                    ->insert($db->qn('league'))
                    ->columns($db->qn(array('name', 'mail')))
                    ->values($db->q($name) . ',' . $db->q($mail));
        $db->setQuery($query);
        $db->execute();
        JFactory::getApplication()->enqueueMessage('Success!', 'message'); // is only reached if no errors
    } catch (Exception $e) {
        if ($e->getCode() == 1062) {
            JFactory::getApplication()->enqueueMessage('Duplicate Email. Please Try Another Email.', 'notice');
        } else {
            JFactory::getApplication()->enqueueMessage('Syntax Error. Please Contact Developer.', 'error');
        }
    }
}

Một số lưu ý nhỏ khác:

  • Tôi đã thực hiện bước xác thực cho đầu vào mail dưới dạng đề xuất phụ trợ.
  • Vì mảng $columns$values Của bạn là "sử dụng một lần", tôi đã quyết định không khai báo chúng và chỉ cần thêm dữ liệu trực tiếp vào các phương thức truy vấn tương ứng.
  • Tôi đang sử dụng q() làm tốc ký cho quote()qn() for quoteName() cho ngắn gọn. Đối với bản ghi, truy vấn của bạn sẽ an toàn/thành công mà không có bất kỳ cuộc gọi qn() nào vì bạn đang sử dụng các từ tĩnh đơn và không có từ nào là MYSQL RESERVED.
  • Để thể hiện quy tắc mà tôi đang tận dụng, hãy xem điều này SQLFiddle Demo cố gắng XÁC NHẬN hai hàng có cùng giá trị email. Nó không hiển thị mã lỗi, chỉ là thông báo lỗi.
2
mickmackusa