2014-12-23 4 views
-3

Я пытаюсь проверить существующую запись в MySQL перед выполнением инструкции INSERT. Если пользователь вводит имя уже в базе данных (поле установлено как уникальное), тогда у них должно быть предложено повторно ввести имя.Проверка MySQL/PHP для дублирования перед INSERT

Проблема, с которой я столкнулась, заключается в том, что если новая запись соответствует записи в любой форме, тогда появляется сообщение об ошибке и не происходит INSERT.

Например, если пользователь вводит DUMMY_NEW и есть запись DUMMY_OLD, они не могут добавить запись, даже если DUMMY_NEW не существует в таблице.

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

код с посторонними битами для ясности:

//Create connection to database using mysqli 
$conn = new mysqli($dbhost, $dbuser, $dbpass, $db); 

//Set variables according to user input on previous form 
$Server_Name = $_POST['Server_Name']; 

//Check for duplicate server name - if exists inform user else run INSERT ($stmt) 
$checkdup = "SELECT * FROM dcr_table WHERE SERVER_NAME = '".$Server_Name."'"; 
$dupresult = $conn->query($checkdup); 

if($dupresult = 1) 
{ 
     print "<br>Error! <p></p>"; 
     echo "" . $Server_Name . " already exists in the DCR"; 
     print "<p></p>Please check the Server Name and try again"; 
} 
else { 


//Define the INSERT statement 
    $stmt = "INSERT INTO dcr_master (Server_Name, Description,..., ... , ...)"; 

//Execute the INSERT statement 
    $conn->query($stmt); 

//Success and return new id 
    echo "<br><p></p>Record Added!<p></p>"; 
    echo "New id: " . mysqli_insert_id($conn); 

//Drop the connection 
    $conn->close(); 
}; 

Edit: Я знаю инъекционной уязвимости. У учетной записи MySQL есть только права SELECT, INSERT и UPDATE для таблицы. Конечный пользователь должен предоставить пароль или отправить сбой. Это небольшое приложение с ограниченным доступом пользователей на данный момент. Строки вывода MySQL будут реализованы после устранения текущей проблемы.

Редакция 2: Использование метода Hobo Sapiens действительно работает при представлении существующей записи, однако новая (пустая) строка по-прежнему добавляется в таблицу. Идентификатор записи по-прежнему автоматически увеличивается, так что я получаю идентификатор № 300 - запись, id # 301 - blank, id # 302 - запись. Является ли это результатом IGNORE в инструкции INSERT?

+1

http://bobby-tables.com/ – hakre

+1

'$ dupresult = 1' - это задание, а не сравнение.Вероятно, вы также захотите проверить '$ conn-> num_results ($ dupresult)> 0' или что-то в этом роде. '$ dupresult' никогда не будет равным 1, потому что это ресурс MySQLi. Помимо этого (и размывающейся SQL-инъекции), ваша логика кажется прекрасной. – Halcyon

+1

Кроме того, $ dupresult должен быть каким-то ресурсом, это просто означает, что запрос преуспел ... о, мой бог, этот код полностью мусор, вы должны его полностью просмотреть. – Sebas

ответ

2

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

Если вы установили столбец SERVER_NAME на номер UNIQUE, вам не нужно проверять наличие имени сервера перед выполнением INSERT, поскольку MySQL сделает это за вас. Используйте INSERT IGNORE объявление проверить количество изменяемых строк после того, как запрос был выполнен, чтобы выяснить, если он работал:

//Create connection to database using mysqli 
$conn = new mysqli($dbhost, $dbuser, $dbpass, $db); 

//Set variables according to user input on previous form 
$Server_Name = $_POST['Server_Name']; 

//Define the INSERT statement with IGNORE keyword 
    $stmt = "INSERT IGNORE INTO dcr_master (Server_Name, Description,..., ... , ...)"; 
    if ($conn->query($stmt) === false) { 
     die("Database error:".$conn->error); 
    } 

// Check for success 
    if ($conn->affected_rows == 0) { 
     print "<br>Error! <p></p>"; 
     echo "" . $Server_Name . " already exists in the DCR"; 
     print "<p></p>Please check the Server Name and try again"; 
    } else { 

//Success and return new id 
     echo "<br><p></p>Record Added!<p></p>"; 
     echo "New id: " . $conn->insert_id; 
    } 

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

Я рекомендую использовать стиль ООП или процедурный стиль для mysqli_*(), но не смешивайте их. Применяются обычные предупреждения об инъекции SQL.

0

Это заявление:

if($dupresult = 1) 

всегда возвращает 1. Вы должны сначала получить первый результат запроса (если таковые имеются), например, так:

$row=$dupresult->fetch_array(MYSQLI_NUM); 

, а затем сравнить результат против NULL:

if(!$row) 
+1

'$ dupresult' - это ресурс MySQLi, при использовании в булевом он всегда будет« true ». – Halcyon

+0

@ Halcyon Если это не 'NULL', где когда-то литые всегда будут« ложными ». Пожалуйста, удалите ваш downvote. – kos

+0

@Halcyon И так как вы даже не нашли времени, чтобы признать свои собственные ошибки, в следующий раз не обходите нисходящие случайные сообщения, если вы даже не знаете, о чем говорите. – kos

1

Использование mysqli_num_rows

$row_cnt = $dupresult->num_rows; 

if ($row_cnt > 0) { 

    echo "There is a matching record"; 

}else { 

    //insert into table 

} 
+0

PHP сообщает об ошибке, когда я добавил этот код. Примечание. Пытается получить свойство не-объекта в строке 48 (строка, содержащая $ row_cnt = $ dupresult-> num_rows;) – Haywood

+1

Это может произойти, если запрос выбора не выполняется. Вы получаете 'false' вместо' [MySQLi resource] '. Вероятно, вы захотите выбросить «Исключение» всякий раз, когда запрос терпит неудачу. – Halcyon

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