|
|
|
| Здравствуйте.
Есть такая загвоздка:
База:
В таблицах базы, ячейки для которых нет информации, должны быть 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 в базу попадает пустая строка, что в обще-то наверно нежелательно.
Как посоветуете быть?
Элементов в форме много - генерировать правильный запрос получается дюже геморройно.
Может по-другому хранить информацию? Или хитро автоматизировать генерирование запроса?
Думается, с подобным вопросом большинство народа сталкивались, как решали? | |
|
|
|
|
|
|
|
для: Niko2
(05.12.2006 в 03:16)
| | kogda sozdaval tablicu nado bilo ukazatj DEFAULT NULL
CREATE TABLE users (
username TINYTEXT,
usercity TINYTEXT DEFAULT NULL
);
potom | |
|
|
|
|
|
|
|
для: Rolands
(05.12.2006 в 03:48)
| | NULL по умолчанию установлен. Это не решает проблемы.
Если мы хотим оставлять в ячейке значение по умолчанию – при инсерте ячейку надо пропускать, а если записывается ‘’ – получается пустая строка а не NUL
Вопрос остается открытым :( | |
|
|
|
|
|
|
|
для: 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 | |
|
|
|
|
|
|
|
для: Rolands
(05.12.2006 в 06:32)
| | Решение понятно.
Вопрос, был, собственно, в том, как такой процедуры избежать.
>> Элементов в форме много - генерировать правильный запрос получается дюже геморройно.
|
что элементов в форме штук 5-10, всяких форм – куча. Генерирование запроса по кусочкам с обсасыванием каждого поля формы – ужжасс %)
Как думаете, без этого можнго обойтись?? :)
Вопрос пока не снялся :( | |
|
|
|
|
|
|
|
для: 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;
.... бла бла бла
|
| |
|
|
|
|
|
|
|
для: Niko2
(13.12.2006 в 01:37)
| | > *Считаеься, что данные для вставки проверены и причесаны от нехороших символов раньше
После этого дальше можно не думать.
Нехороших символов не бывает. Все символы одинаково хороши. При написании универсальных функций следует исходить именно из этой предпосылки. | |
|
|
|
|
|
|
|
для: Trianon
(13.12.2006 в 10:19)
| | Фраза в комментарии, вызвавшая критику всего лишь означает, что данная функция не занимается проверкой данных пользователя, экранированием тегов, спецсимволов и проч. Она лишь генерирует кусок запроса оставляя пропуски там, где надо.
Проверка данных и проч. проводится несколько раньше. | |
|
|
|
|
|
|
|
для: Niko2
(13.12.2006 в 16:00)
| | Универсальная функция и не должна проверять данные на вшивость. Она должна исходить из того, что если на её вход подали определенную символьную строку, то именно такую строку она должна поместить в качестве значения поля таблицы. Даже если эта строка состоит из одного единственного апострофа. | |
|
|
|
|
|
|
|
для: 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 не проверял, но мне кажется должно заработать | |
|
|
|