избегая пустых и дублированных записей, представленных в sql - PullRequest
3 голосов
/ 12 декабря 2011

Я борюсь с логикой этого кода. Я думаю, что пустые записи появляются при использовании кнопки "Назад". Это система анкетирования для учеников с ограниченными возможностями, где на страницу задается только 1 вопрос, а результаты представляются индивидуально для каждого вопроса. Существует отдельная таблица для определения того, был ли опрос полностью завершен (я отслеживаю уникальный идентификатор с помощью GET), и результаты получаются только из тех, которые были полностью заполнены.

Я пытался использовать отклик / комментарий UPDATE, когда существуют такие варианты: queitonID и Unique ID, но это, похоже, создает больше проблем. Для ясности и для обеспечения некоторой свободы идей я сократил код до минимума. Большое спасибо.

РЕДАКТИРОВАТЬ: «ответ» - это запись переключателя, а «комментарий» - ввод текста. «UniqueID», «surveyID», «QID» и «тип» определяются в URL-адресе и регистрируются с помощью GET.

mysql_query("

INSERT INTO answers (uniqueID, surveyID, QID, type, response, comment) 
SELECT '$U', '$S','$Q', '$t', '$response', '$comments' 

") 
or die(mysql_error());  


if (isset($_GET['start']))   {

mysql_query("

INSERT INTO complete (uniqueID, surveyID) 
VALUES('$U', '$S') 

") 
or die(mysql_error()); 

}     

if (isset($_GET['finished']))   { 

mysql_query("

UPDATE complete 
SET timestamp = NOW() 
WHERE uniqueID='$U' 

") 
or die(mysql_error()); 

}

Ответы [ 2 ]

1 голос
/ 12 декабря 2011

Ваш код не выполняет никакой проверки, он просто die s при возникновении ошибки.
Это не будет делать в производственном коде.

Что касается проверки, у вас есть 2 варианта:

A - Проверить ввод в php и запретить любые недопустимые значения.
B - Использовать ограничения SQL и отслеживать вывод там.
Или комбинация двух.

Проблема с опцией B заключается в том, что вы просто получите ошибку от MySQL, которую вам придется обработать в php.
По этой причине я бы выбрал вариант А.

Первый шаг: экранирование ввода
Лучший способ сделать это - использовать PDO .
Если вы используете mysql_ lib, вам придется использовать mysql_real_escape_string на каждом входе, чтобы экранировать его и заключить в кавычки $vars; вот так:

$a = mysql_real_escape_string($_GET['param1']);
examplequery = "SELECT * FROM table1 WHERE field1 = '$a' ";

Для целочисленных значений вы можете преобразовать переменную в целое, а затем вставить ее без кавычек.

$a = intval($_GET['param1']);
$b = intval($_GET['param2']);
if $a > $b { list($a,$b) = array($b,$a); }  //Exchange the two vars if needed.
examplequery = "SELECT * FROM table1 WHERE field1 BETWEEN $a AND $b";

Проверка ваших данных
Здесь снова у вас есть два варианта: вы можете жестко закодировать проверку в php или использовать SQL для проверки ввода.
Мне нравится второй подход, потому что он позволяет вам поместить всю информацию в действительный ввод в базу данных.

Проверка ваших данных с использованием таблицы проверки
Один из вариантов - создать таблицу примерно так:

table Checks (
  fieldname varchar(50) not null,
  tablename varchar(50) not null,
  fieldtype enum('int','varchar','enum','decimal'.....) not null,
  min_value double default -1000000;
  max_value double default 1000000;
  validation_query varchar(1000) default null, 
  primary key (tablename, fieldname)) ENGINE = InnoDB;

Теперь вы можете проверить параметр следующим образом (используя PDO):

$stmt = $dbh->prepare("SELECT fieldtype, min_value, max_value, validation_query
                       FROM checks WHERE fieldname = ? AND tablename = ?");
$stmt->execute(array('field1', 'table1'));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
switch ($result['type']) {
  case 'int':
    $allOK = isnumeric($inputvalue_to_check); 
    $allOK = $allOK AND ($intval($inputvalue_to_check) >= $result['min_value']
                     AND $intval($inputvalue_to_check) <= $result['max_value']);
    if is_null($result['validation_query']) {
      $sql = $result['validation_query'];
      $check = $dbh-?prepare($sql);
      $check_result = $check->execute(array($inputvalue_to_check));
      $check_result->fetch(PDO::FETCH_ASSOC);
      if is_null($check_result['result']) { //value is not OK}
    break;
  case .......

Подтверждение в php
Если вы знаете свои данные и они не подлежат изменению, вы можете выполнить проверку, используя операторы if и switch.
Этот код очень похож на приведенный выше код, за исключением того, что он не извлекает данные из базы данных, вместо этого логика жестко запрограммирована или хранится в структурах данных php.

1 голос
/ 12 декабря 2011

Если вы спросите, как заставить mysql жаловаться при вставке повторяющихся или пустых значений, ответ будет:

  • УНИКАЛЬНОЕ ограничение на (uniqueID, surveyID, QID) для избежания дублирования
  • Ограничение NOT NULL для избежания пустых значений

для чтения ограничений, включенных в Документы MySQL

Но я бы также проверил в PHP, присутствуют ли указанные значения и правильно ли они отформатированы. Не говоря уже о том, что SELECT '$U', '$S','$Q', '$t', '$response', '$comments' способ написания запросов очень опасен, поскольку допускает внедрение кода различного типа.

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