Какой лучший способ проверить, существует ли значение в таблице sqlite? - PullRequest
1 голос
/ 21 июня 2011

Первый вопрос здесь, поэтому, пожалуйста, не бейте меня, если я делаю что-то глупое!

Я создаю систему входа в систему, включая регистрацию и т. Д., И при регистрации мне нужно протестировать 3 вещи, чтобы убедиться, что они уже используются.

Мой начальный тестовый код выглядит примерно так:

$IDq = $userdbc->query("SELECT * FROM users WHERE userID = '$uID'");
$IDq->setFetchMode(PDO::FETCH_ASSOC);
$IDf = $IDq->fetch();
if($IDf['userID']){
    echo '<p>ID exists</p>';
}
else{
    echo '<p>ID does not exist?</p>';
}

Мне нужно проверить наличие возможных дубликатов электронной почты и отображаемых имен. Я уверен, что должен быть лучший способ сделать это?

Или мне действительно придется повторить процесс 3 раза для проверки каждого элемента?

Это мое первое настоящее предприятие, использующее решение для баз данных. Любая полезная информация очень ценится - заранее спасибо!

РЕДАКТИРОВАТЬ: мне нужно проверить каждое значение в отдельности, чтобы я мог перестроить регистрационную форму с соответствующим сообщением об ошибке с указанием именно того, что нужно изменить. Извините, я должен был быть более конкретным.


РЕДАКТИРОВАТЬ: Решение - спасибо Шакти Сингх и всем остальным за помощь.

Функция (с использованием подготовленного оператора с именованным заполнителем):

function item_exists($dbc, $col, $val){
    $query = $dbc->prepare("SELECT * FROM users WHERE $col = :val");
    $query->execute(array(':val' => $val));
    $fetch = $query->fetch();
    if($fetch[$col]){
        return true;
    }
    else{
        return false;
    }
}

Как я использую его в своей функции проверки регистрации:

$userdbc = new PDO('sqlite:db/users.s3');

if(item_exists($userdbc, 'userID', $_POST['id'])){
    $valid = false;
    array_push($sub['e'], 'User ID is not available.');
}
if(item_exists($userdbc, 'userEmail', $_POST['email'])){
    $valid = false;
    array_push($sub['e'], 'Email Address is already in use.');
}
if(item_exists($userdbc, 'userName', $_POST['name'])){
    $valid = false;
    array_push($sub['e'], 'Display Name already taken.');
}
$userdbc = null;

РЕДАКТИРОВАТЬ: Дополнительно:

Поскольку я тестирую только один элемент, в рамках функции item_exists(), которую я заменил:

$query->execute(array(':val' => $val));

для:

$query->bindParam(':val', $val);
$query->execute();

.. только потому, что выполнение массива показалось мне глупым, поскольку он содержит только один ключ / значение ..

Не знаю, какова может быть реальная разница, но эй, есть еще один вариант.

РЕДАКТИРОВАТЬ: Дополнительные-Дополнительные:

Функция со всеми внесенными изменениями:

function item_exists($dbc, $col, $val, $rn){
    // updated the prepare statement as per James Anderson's suggestion.
    $query = $dbc->prepare("SELECT COUNT($col) AS dupli FROM users WHERE $col = :val");
    $query->bindParam(':val', $val);
    $query->execute();
    $fetch = $query->fetch();
    // $fetch['dupli'] contains the number of matches found.
    // $fetch[0] should also work, but not tested.
    if($rn){ // if $rn = true, return the number of finds
        return $fetch['dupli'];
    }
    else{ // else we are just testing for a match so..
        if($fetch['dupli'] > 0){ // if we have one
            return true;
        }
        else{
            return false;
        }
    }
}

Я просто чувствовал, что должен добавить это на тот случай, если кто-то еще будет бороться, как я, всегда приятно иметь рабочие примеры - с комментариями тоже ^ _ ~

Я вполне уверен, что это будет мое последнее редактирование, но ... никогда не знаешь.

Ответы [ 4 ]

2 голосов
/ 21 июня 2011

Не повторяйте процесс 3 раза для проверки каждого элемента.

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

function item_exists($item_value,$item_type)
{
   $IDq = $userdbc->query("SELECT * FROM users WHERE $item_type= '$item_value'");
   $IDq->setFetchMode(PDO::FETCH_ASSOC);
   $IDf = $IDq->fetch();
   if($IDf[$item_type])
   {
     return true;
   } 
   else
   {
     return false;
   }
}

И вызывать такую ​​функцию

if (item_exists($userID, 'userID') === true)
{
     echo 'user_id exists';
}

if (item_exists($emailID, 'email') === true)
{
     echo 'email exists';
}

Этот метод позволит вам узнать, что дублируется.так что вы можете показать как сообщение для конечного пользователя.

1 голос
/ 21 июня 2011

Это три разных теста, так почему бы не три SQL?

Вы можете и должны изменить свой "select *" на "select count(*) as idcount", так как тогда весь запрос может быть удовлетворен только с помощью доступа к индексу.

Если вы действительно хотите сделать это в одном SQL, тогда:

    Select sum(DUP_USER) as du, sum(DUP_NAME) as dn, Sum(DUP_EMAIL) as de 
from (
    Select Case when userId = '$Uid' then 1 Else 0 End AS DUP_USER
           Case when userName = '$uname' then 1 Else 0 End AS DUP_NAME
           Case when userEmail = '$uEmail' then 1 Else 0 End as DUP_EMAIL
    From users
     WHERE userID= '$uID' 
        OR userName = '$uName' 
        OR userEmail = '$uEmail' )

Но, честно говоря, три отдельных SQL гораздо более читабельны.

0 голосов
/ 21 июня 2011

Вы всегда можете использовать оператор OR:

$IDq = $userdbc->query("SELECT * FROM users WHERE userID = '$uID' OR email='$email' OR displayName='$displayName'");
$IDq->setFetchMode(PDO::FETCH_ASSOC);
$IDf = $IDq->fetch();

echo ($IDf['userID'] == $uID) ? '<p>ID exists</p>' : '<p>ID does not exist?</p>';
echo ($IDf['email'] == $email) ? '<p>Email exists</p>' : '<p>Email does not exist?</p>';
echo ($IDf['displayName'] == $displayName) ? '<p>DisplayName exists</p>' : '<p>DisplayName does not exist?</p>';

Я надеюсь, что вы экранируете значения перед отправкой их в базу данных и просто пропустили эту часть в своем сообщении.В противном случае вы открыты для SQL-инъекций

0 голосов
/ 21 июня 2011

Вместо того, чтобы делать это трижды, просто добавьте условие в предложение WHERE, например

WHERE userID= '$uID' OR userName = '$uName' OR userEmail = '$uEmail'

Так что при выполнении этого условия, если любое из условий удовлетворяет, вы получите строку, а затем выВы узнаете, что существует повторяющаяся запись

РЕДАКТИРОВАТЬ

Для дальнейшего чтения по ИЛИ - отметьте Планировщик запросов SQLite в разделе ИЛИоптимизаций

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...