andrystepa
Помогающий
Offline
|
|
« : 26-03-2009 12:12 » |
|
Есть база данных на MySQL. Пишу на PHP интерфейс пользователя. В частности надо добавлять в одну из таблиц базы записи о новых проектах. Запись включает название проекта, дату начала, дату завершения и его статус. Пользователь на Web странице вводит в текстовые поля эти данные. Я вставляю полученные строки в запрос: $sql = "INSERT INTO Proj (Prj_name, Start_D, Stop_D, Status) VALUES ('$Pname', $startd, $stopd, 1);";
Но тут проблема - переменные $stastd и $stopd - это строки, а в таблице хранятся данные в виде числа секунд. Поэтому такой запрос MySQL не поймет. Если делать из консоли mysql - понимает, а средствами PHP - нет. Есть ли какая-нибудь функция конвертации строки с датой в понятный для MySQL формат?
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #1 : 26-03-2009 12:40 » |
|
есть strtotime();
|
|
« Последнее редактирование: 26-03-2009 12:42 от Sla »
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
andrystepa
Помогающий
Offline
|
|
« Ответ #2 : 26-03-2009 13:56 » |
|
Посмотрел сюда: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.htmlНету там такой функции. Есть функция STR_TO_DATE(). Только вот опять в консоли срабатывает, а из-под PHP не хочет: Код такой: $sql = "INSERT INTO Proj (Prj_name, Start_D, Stop_D, Status) VALUES ('$Pname', SELECT STR_TO_DATE('$startd', %Y-%m-%d), 0, 1);"; $result = getquery($sql); if ($result) { print "<br>"; print $sql; print "<br>"; $sql1 = "SELECT * FROM Proj;"; $result = getquery($sql1); print <<<HERE <div align="center"> HERE; print showtable($result); print <<<HERE </div>; HERE; } else { print "Query Error1"; $tsql = "SELECT STR_TO_DATE('$startd', '%Y-%m-%d');"; $res = getquery($tsql); print"<br>"; print $res; print "<br>"; print $sql; }
Функция getquery($query) и showtable($result) - это мои функции. Одна - оболочка для mysql_query(), а вторая выводит таблицу из запроса. Обе работают без пробелем - уже не раз применял. $startd - берется из текстового поля ввода на веб-странице. Вот что получается при добавлении: Query Error1 STR_TO_DATE('2008-01-01', '%Y-%m-%d') 2008-01-01
INSERT INTO Proj (Prj_name, Start_D, Stop_D, Status) VALUES ('Ангола', SELECT STR_TO_DATE('2008-01-01', %Y-%m-%d), 2009-10-01, 1);
Это то, что было на веб-странице, показывающей результат. Странно. Вроде вложенный запрос должен сработать, а выдает ошибку. В чем она?
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #3 : 26-03-2009 14:14 » |
|
а может так? STR_TO_DATE('2008-01-01', '%Y-%m-%d')
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Sla
|
|
« Ответ #4 : 26-03-2009 14:15 » |
|
strtotime(); так то для php
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
andrystepa
Помогающий
Offline
|
|
« Ответ #5 : 26-03-2009 14:21 » |
|
Попробовал. Нифига не изменилось. Только запрос на веб странице теперь печатается так: INSERT INTO Proj (Prj_name, Start_D, Stop_D, Status) VALUES('Ангола', SELECT STR_TO_DATE('2008-01-01', '%Y-%m-%d'), 2009-10-01, 1);
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #6 : 26-03-2009 14:32 » |
|
<?php
date('Y-m-d' ,strtotime($startd));
?>
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Sla
|
|
« Ответ #7 : 26-03-2009 15:06 » |
|
что ты получаешь запросом? SELECT STR_TO_DATE('2008-01-01', '%Y-%m-%d'), 2009-10-01, 1)
наверное надо SELECT STR_TO_DATE('2008-01-01', '%Y-%m-%d'), STR_TO_DATE('2009-10-01','%Y-%m-%d'), 1)
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Sla
|
|
« Ответ #8 : 26-03-2009 15:08 » |
|
McZim, я думаю, что решение о дате, все же лучше отдать в СУБД в php надо проверить только корректность формата даты
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
andrystepa
Помогающий
Offline
|
|
« Ответ #9 : 26-03-2009 17:37 » |
|
Странно. Попробовал отдельно напечатать: print "результат преобразования: "; print strtotime($startd));
В результате получил на странице: результат преобразования: И все! Что-то не так. Строку вводил в формате YYYY/mm/dd - то есть 2008/01/01 как написано в моем справочнике.
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #10 : 26-03-2009 19:08 » |
|
<?php $str = '2009/03/26'; $date = date('Y/m/d' ,strtotime($str)); echo $date ?>
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Sla
|
|
« Ответ #11 : 26-03-2009 19:43 » |
|
andrystepa, почитай про strtotime, много интересного по большому счету должно было вернуть -1
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
andrystepa
Помогающий
Offline
|
|
« Ответ #12 : 27-03-2009 07:08 » |
|
В преобразовании ошибку нашел: в функции strtotime(str, [int]) строку с датой надо ставить в кавычки. То есть для моего случая: strtotime("$startd"); strtotime("$stopd"); Все поправил. Код получился такой: $strd = strtotime("$startd"); $stfd = strtotime("$stopd"); $sql = "INSERT INTO Proj (Prj_name, Start_D, Stop_D, Status) VALUES('$Pname', '$strd', '$stfd', 1);"; print "<br>"; print "Используем следующий запрос:"; print "<br>"; print $sql; print "<br>"; $result = getquery($sql); if ($result) { print "<br>"; print "<br>"; $sql1 = "SELECT * FROM Proj;"; $result = getquery($sql1); print <<<HERE <div align="center"> HERE; print showtable($result);
в ответ получил следующее: Используем следующий запрос: INSERT INTO Proj (Prj_name, Start_D, Stop_D, Status) VALUES('Проект4', '1199134800', '1254340800', 1);
Вроде с запросом все в порядке. Дата преобразовалась. Ан нет. В таблице вижу такое: mysql> SELECT * FROM Proj; +--------+----------+------------+------------+--------+ | Prj_Id | Prj_name | Start_D | Stop_D | Status | +--------+----------+------------+------------+--------+ | 2 | Проект1 | 2007-06-01 | 2010-06-01 | 1 | | 3 | Проект2 | 1900-01-01 | 1900-10-01 | 0 | | 4 | Проект3 | 1892-03-01 | 2007-10-01 | 0 | | 6 | Проект4 | 0000-00-00 | 0000-00-00 | 1 | +--------+----------+------------+------------+--------+ 4 rows in set (0.00 sec)
То есть даты, зараза, опять вставились нулевые! Почему? Что еще требуется?
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #13 : 27-03-2009 07:40 » |
|
Используем следующий запрос: INSERT INTO Proj (Prj_name, Start_D, Stop_D, Status) VALUES('Проект4', '1199134800', '1254340800', 1);
andrystepa, а что это за даты такие у тебя чудесные? Очень напоминает unix timestamp... Внимательно читаем мануал! http://dev.mysql.com/doc/refman/5.0/en/datetime.html1. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format. 2. MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. 3. You can specify DATETIME, DATE, and TIMESTAMP values using any of a common set of formats: - As a string in either 'YYYY-MM-DD HH:MM:SS' or 'YY-MM-DD HH:MM:SS' format.
- As a string in either 'YYYY-MM-DD' or 'YY-MM-DD' format.
- As a string with no delimiters in either 'YYYYMMDDHHMMSS' or 'YYMMDDHHMMSS' format, provided that the string makes sense as a date.
- As a string with no delimiters in either 'YYYYMMDD' or 'YYMMDD' format, provided that the string makes sense as a date.
- As a number in either YYYYMMDDHHMMSS or YYMMDDHHMMSS format, provided that the number makes sense as a date.
- As a number in either YYYYMMDD or YYMMDD format, provided that the number makes sense as a date.
- As the result of a function that returns a value that is acceptable in a DATETIME, DATE, or TIMESTAMP context, such as NOW() or CURRENT_DATE.
4. UNIX TIMESTAMP не является календарным типом - это целое число. По этому его нельзя присваивать и сравнивать с датами напрямую - для этого есть функции преобразования. http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_from-unixtimehttp://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_unix-timestamp
|
|
« Последнее редактирование: 27-03-2009 07:42 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
andrystepa
Помогающий
Offline
|
|
« Ответ #14 : 27-03-2009 08:31 » |
|
То есть для того чтобы строку с датой, введенную пользователем вставить в базу данных MySQL как дату надо ее сначала преобразовать в UNIX_TIMESTAMP а потом снова преобразовать в дату? А напрямую нельзя?
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #15 : 27-03-2009 09:23 » |
|
andrystepa, не придумывай сложностей на свою голову!
В каком формате у тебя дата в программе? Ты мануал по PHP смотрел?
Функция strtotime() возвращает unix timestamp. Дата в формате unix timestamp - это число, означающее количество секунд, прошедшее с 1.01.1970 00:00:00.
Теперь тебе надо это преобразовать в один из разрешенных для вставки в столбец DATE форматов (см. мой пост выше).
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
andrystepa
Помогающий
Offline
|
|
« Ответ #16 : 27-03-2009 12:53 » |
|
Жалко. Если бы была функция преобразующая напрямую - это было бы проще чем использовать две функции - преобразовать сначала в UNIX_TIMESTAMP, а потом в нужный формат.
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #17 : 27-03-2009 12:58 » |
|
andrystepa, есть решение!!! Сразу помещать в переменную данные нужного формата.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
andrystepa
Помогающий
Offline
|
|
« Ответ #18 : 27-03-2009 18:49 » |
|
McZim, А как это делается, если не секрет? Я ведь получаю данные из текстового поля ввода на web странице. А это текстовая строка. Я видел на web страницах поля выбора даты с календарем. Может они выдают данные в виде даты. Но как они реализуются я понятия не имею.
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #19 : 27-03-2009 19:11 » |
|
andrystepa, давай с календарем разберемся позжее 1. Получить данніе от пользователя. 2. Провести валидацию данніх 2.а проверить правильность формата данных, например dd-mm-yyyy 2.b проверить диапазон дат (29-02, 28-02 3. Преобразовать в unixstamp 4. Преобразовать в формат даты СУБД 4 необходимых условия
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
andrystepa
Помогающий
Offline
|
|
« Ответ #20 : 09-04-2009 13:09 » |
|
Черт побери. Теперь не удается правильно составить запрос на вставку. Я сделал такой запрос: INSERT INTO Proj (Prj_name, Start_D, Stop_D, Status) VALUES ('Ангола', Start_D, Stop_D, 1) SELECT FROM_UNIXTIME(1199134800) AS Start_D, FROM_UNIXTIME(1254340800) AS Stop_D; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT FROM_UNIXTIME(1199134800) AS Start_D, FROM_UNIXTIME(1254340800) AS Stop_D' at line 1
Ошибка! Я видимо неправильно составил запрос. Но не знаю в чем. Шаблон для запроса я взял в книжке по MySQL 5 Кузнецова Симдянова. Что неправильно?
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #21 : 09-04-2009 13:37 » |
|
andrystepa, видимо ты совсем не понимаешь SQL... VALUES и SELECT никак не могут быть в одном INSERT! Прочти внимательно мануал - синтаксис команд там описан.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
andrystepa
Помогающий
Offline
|
|
« Ответ #22 : 10-04-2009 06:12 » |
|
Спасибо. Меня сбила с толку книга "MySQL 5 в подлиннике" авторы Максим Кузнецов, Игорь Симдянов. Там в пункте 24.8 "Вложенные запросы в операторе INSERT" был такой пример: INSERT INTO new_orders VALUES (id_order, ordertime, product, user) SELECT orders.id_order AS id_order, orders.ordertime AS ordertime, --> products.name AS product FROM orders, users, products WHERE orders.id_user = users.id_user AND --> orders.id_product = products_id_product;
В соответствии с этим примером я и сделал запрос. Что-ж, значит врут писатели.... А эту книжку многие рекомендовали. Работает вот такая конструкция ( это код в странице на php): $strd = strtotime("$startd"); $stfd = strtotime("$stopd"); $sql = "INSERT INTO Proj (Prj_name, Start_D, Stop_D, Status) SELECT '$Pname', FROM_UNIXTIME($strd), FROM_UNIXTIME($stfd), 1;";
где $startd, $stopd и $Pname получены из формы ввода. То есть тот же запрос, только без VALUES.
|
|
|
Записан
|
|
|
|
RuNTiME
|
|
« Ответ #23 : 10-04-2009 06:29 » |
|
andrystepa, вот тебе функция, которая преобразовывает дату из строкового формата в Unix Stamp с проверкой входных данных. Воспринимаются входные строки: ДД.ММ.ГГ, ДД.ММ.ГГГГ, ДД/ММ/ГГ, ДД/ММ/ГГГГ, ДД\ММ\ГГ, ДД\ММ\ГГГГ //преобразовывает дату из строкового формата в штамп function dt_str_to_date($value) { $match = 0; if( ereg('^([0-9]{1,2})[/|.|\\]([0-9]{1,2})[/|.|\\]([0-9]{2,4})$', $value, $match) ) { if( ($ret = strtotime("{$match[2]}/{$match[1]}/{$match[3]}")) ) { return $ret; } } return NULL; }
Если дату преобразовать не удалось, то функция вернёт NULL, что ты легко сможешь проверить.
|
|
|
Записан
|
Любимая игрушка - debugger ...
|
|
|
Sla
|
|
« Ответ #24 : 10-04-2009 06:49 » |
|
RuNTiME, не сканает
99/99/9999 чего ereg вернет?
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Sla
|
|
« Ответ #25 : 10-04-2009 06:53 » |
|
не большой спец в регулярках
ereg('^([0-3]?[0-9]{1,2})[/|.|\\]([0|1]?[0-9]{1,2})[/|.|\\]([0-9]{2,4})$');
присмотрелся, кажется так лучшее
ereg('^([0-3]?[0-9]?)[/|.|\\]([0|1]?[0-9]?)[/|.|\\]([0-9]{2,4})$');
но и тут 39/19/9999
|
|
« Последнее редактирование: 10-04-2009 06:56 от Sla »
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
RuNTiME
|
|
« Ответ #26 : 10-04-2009 07:40 » |
|
Sla, варианты с 39/19/9999, 99/99/9999 ну и тому подобные не пропустит strtotime()... так что проблемы не вижу... регулярки в основном тут используются для того, чтобы распарсить дату и выставить в правильном порядке день, месяц и год для strtotime().
|
|
« Последнее редактирование: 10-04-2009 07:58 от RuNTiME »
|
Записан
|
Любимая игрушка - debugger ...
|
|
|
|