Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Вставка в базу значений NULL для незаполненных полей формы
 
 автор: Niko2   (05.12.2006 в 03:16)   письмо автору
 
 

Здравствуйте.
Есть такая загвоздка:
База:
В таблицах базы, ячейки для которых нет информации, должны быть NULL
Например:

UserName | UserCity 
-------------------------
Вася | Замухранск 
----------------------
Петя | NULL 

То есть, Петя не пожелал заполнить в анкете поле «Город», а может быть, забыл, где живет :)

Далее к самой анкете.
Чтоб получить такую таблицу надо выполнить следующий запрос:

INSERT INTO `Users` ( ` UserName ` , ` UserCity ` ) 
VALUES ( 
'ВАСЯ', 'Замухранск'
), ( 
'ПЕТЯ', NULL 
);

Проблема возникает при формировании запроса из ПХП

Запрос в PHP формируем так:


$guery=
"
INSERT INTO `Users`
( ` UserName ` , ` UserCity ` )
VALUES
 ('".$_POST['UserName']."', '".$_POST['UserCity']."');
";

И получается, что, когда Петя не ввел в форму значение «Город», информация о нем прописывается запросом:

INSERT INTO `Users`
( ` UserName ` , ` UserCity ` )
VALUES
 ('Петя', ‘’);

А надо бы:

INSERT INTO `Users`
( ` UserName ` , ` UserCity ` )
VALUES
 ('Петя', NULL);

Получается, что вместо NULL в базу попадает пустая строка, что в обще-то наверно нежелательно.

Как посоветуете быть?
Элементов в форме много - генерировать правильный запрос получается дюже геморройно.
Может по-другому хранить информацию? Или хитро автоматизировать генерирование запроса?
Думается, с подобным вопросом большинство народа сталкивались, как решали?

   
 
 автор: Rolands   (05.12.2006 в 03:48)   письмо автору
 
   для: Niko2   (05.12.2006 в 03:16)
 

kogda sozdaval tablicu nado bilo ukazatj DEFAULT NULL

CREATE TABLE users (
username TINYTEXT,
usercity TINYTEXT DEFAULT NULL
);

potom

   
 
 автор: Niko2   (05.12.2006 в 04:04)   письмо автору
 
   для: Rolands   (05.12.2006 в 03:48)
 

NULL по умолчанию установлен. Это не решает проблемы.
Если мы хотим оставлять в ячейке значение по умолчанию – при инсерте ячейку надо пропускать, а если записывается ‘’ – получается пустая строка а не NUL

Вопрос остается открытым :(

   
 
 автор: Rolands   (05.12.2006 в 06:32)   письмо автору
 
   для: Niko2   (05.12.2006 в 04:04)
 

nu mozhno tak

if($_POST['UserCity'])
$guery="INSERT INTO `Users`
( ` UserName ` , ` UserCity ` )
VALUES
 ('"$_POST['UserName']."', '"$_POST['UserCity']."');
"; 
else
$guery="INSERT INTO `Users`
( ` UserName ` )
VALUES
 ('"$_POST['UserName']."');
"; 

dolzhno rabotatj

   
 
 автор: Niko2   (05.12.2006 в 13:47)   письмо автору
 
   для: Rolands   (05.12.2006 в 06:32)
 

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


>> Элементов в форме много - генерировать правильный запрос получается дюже геморройно. 


что элементов в форме штук 5-10, всяких форм – куча. Генерирование запроса по кусочкам с обсасыванием каждого поля формы – ужжасс %)
Как думаете, без этого можнго обойтись?? :)

Вопрос пока не снялся :(

   
 
 автор: Niko2   (13.12.2006 в 01:37)   письмо автору
 
   для: Rolands   (05.12.2006 в 06:32)
 

Вот написал фиговину, с помощью которой решаю эту проблему.
Функция претендует на универсальность и используется в любых insert – запросах.

Интересно, что об этой фиговине думают асы? :))))


// СПЕЦФУНКЦИЯ 
function GetInsertLine($insert_array)
/* Функция возвращает кусок insert-запроса после SET типа:
  `ColumnName1`='LineValue1',
  `ColumnName2`='LineValue2'
без последней запятой

на входе функции д.б. массив типа:
array=
(
 array ('Имя столбца', 'Значение,которое туды пишеццо', null-признак)
 array (....)
)
Функция осуществляет вставку значений по умолчинию базы вместо пустых значений если оно надо
Если NULL-признак = TRUE
  --- встречая пустое значение оно ПРОПУСКАЕТСЯ (в базу попадает значение по умолчанию опредененное структурой базы для этого столбца)
Если NULL-признак = FALSE
 --- пустое значение вставляется без изменений

*Считаеься, что данные для вставки проверены и причесаны от нехороших символов раньше
*/
{
if (!is_array($insert_array)) error ("function InsertLine: неправильные данные");
$set_query="";
for ($i=0;$i<count($insert_array); $i++)
{

if ($insert_array[$i][2])
 {
  if (!empty($insert_array[$i][1]))
  $set_query.="`".$insert_array[$i][0]."`='".$insert_array[$i][1]."',";

 }
else
 $set_query.="`".$insert_array[$i][0]."`='".$insert_array[$i][1]."',";
}

// вырезаем последнюю запятую
$set_query = substr($set_query,0,strlen($set_query)-1);

return $set_query;
}


// ОСНОВНОЙ СЦЕНАРИЙ 
$insert_array= array
(
array('UserName',$_POST('UserName',1),
array('UserCity',$_POST('UserCity',1)
);

$set_query = GetInsertLine($insert_array);

// монтируем окончательный запрос вставки, с которым далее полезем в базу 
$guery=
 "
 INSERT INTO `Users`
  SET ".
 $set_query;
 
.... бла бла бла

   
 
 автор: Trianon   (13.12.2006 в 10:19)   письмо автору
 
   для: Niko2   (13.12.2006 в 01:37)
 

> *Считаеься, что данные для вставки проверены и причесаны от нехороших символов раньше

После этого дальше можно не думать.

Нехороших символов не бывает. Все символы одинаково хороши. При написании универсальных функций следует исходить именно из этой предпосылки.

   
 
 автор: Niko2   (13.12.2006 в 16:00)   письмо автору
 
   для: Trianon   (13.12.2006 в 10:19)
 

Фраза в комментарии, вызвавшая критику всего лишь означает, что данная функция не занимается проверкой данных пользователя, экранированием тегов, спецсимволов и проч. Она лишь генерирует кусок запроса оставляя пропуски там, где надо.
Проверка данных и проч. проводится несколько раньше.

   
 
 автор: Trianon   (13.12.2006 в 16:37)   письмо автору
 
   для: Niko2   (13.12.2006 в 16:00)
 

Универсальная функция и не должна проверять данные на вшивость. Она должна исходить из того, что если на её вход подали определенную символьную строку, то именно такую строку она должна поместить в качестве значения поля таблицы. Даже если эта строка состоит из одного единственного апострофа.

   
 
 автор: Dobryy   (13.12.2006 в 11:33)   письмо автору
 
   для: Niko2   (05.12.2006 в 03:16)
 

если я правильно понял проблему, то это можно решить таким способом, только имена полей формы нужно назывть именами полей в таблице, что может несколько облегчить MySQL инъекцию, если код уязвим

<?
foreach($_POST as $k=>$v){ // или любой другой массив
    
if (!empty($v)) {
        
$keys[] = $k;
        
$values[] = $v;
    }
}
$sql "insert into tbl (`".implode("`,`",$keys)."`) values ('".implode("','",$values)."')";                             
?>

PS не проверял, но мне кажется должно заработать

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования