С DAO сталкивался давным-давно, но не помню почему - на ODBC остановился. Я разные форматы даты пытался скормить Access'у. В том числе и такой:
INSERT INTO [User] ( id, date)
VALUES (1, #2014-02-02#);
Но он даже сохранять такой запрос не хочет, говоря, что допущена ошибка синтаксиса в операторе INSERT
[WinAPI] Как через SQLExecDirect передать дату SQL-запросу?30.03.15 12:05 Автор: Vedrus <Serokhvostov Anton> Статус: Member Отредактировано 30.03.15 12:07 Количество правок: 2
И вновь я с извращенским вопросом. Понимаю, что сейчас на низком уровне программировать БД уже не модно, но мне очень надо ))). Работаю с Visual C++ 6.0 (понимаю, антиквариат – ну люблю я её…) Мне надо, чтобы заработал примерно такой код:
wsprintf(szQuery, "INSERT INTO User (id, date) VALUES (%d, '%s')", dwId, "#23.07.2014#");
ret = SQLExecDirect(hStmt, (SQLTCHAR *) szQuery, lstrlen(szQuery))
Но вот не хочет он работать. Считывать уже ранее занесённое в БД значение даты получается в переменную типа DATE_STRUCT, но вот обратное действие – запись в БД, не могу придумать как сделать.
Перекопал заголовочные файлы с датой, в МСДН прокопался, но так ничего и не додумал. Подскажите пожалуйста, как проделать этот трюк?
PS. В Качестве СУБД использую MS Access. Но даже там при ручном формировании запроса так и не смог понять, в каком виде оператору INSERT дату передавать.
Плохо пишешь... Без экранирования введенных пользователем данных рискуешь получить SQL-injection [upd]30.03.15 15:35 Автор: Den <Денис Т.> Статус: The Elderman Отредактировано 01.04.15 10:33 Количество правок: 3
Если запрос выполняется единожды и больше не повторяется в процессе работы программы, то SQLExecDirect, конечно, можно использовать. В остальных случаях лучше использовать параметризованный запрос, подготовленный с помощью SQLPrepare.
После подготовки запроса тебе надо сделать SQLBindParameter, затем SQLExecute. Пример использования смотри в конце описания функции SQLBindParameter.
[upd]
> PS. В Качестве СУБД использую MS Access. > Но даже там при ручном формировании запроса так и не смог понять, > в каком виде оператору INSERT дату передавать.
В самом Access'е дата должна представляться внутри запроса через '#' без символов строки
"INSERT INTO User (id, date) VALUES (0, #23.07.2014#)"
Самый вменяемый хелп по ассексу присутствует только в MS Access 97. Хелпы последующих ассексов выглядят как шлак. Вот о чем нам повествует вышеупомянутый хелп:
"Переменные типа Date (значения даты и времени) сохраняются как 64-разрядные (8-байтовые) числа с плавающей точкой стандарта IEEE, представляющие даты в диапазоне от 1 января 100 г. до 31 декабря 9999 г. и значения времени от 0:00:00 до 23:59:59. Переменным типа Date могут быть присвоены любые значения, задаваемые распознаваемыми датами в явном представлении (литералами даты). Литералы даты следует окружать символами (#), например, #January 1, 1996# или #1 Jan 96#.
Значения типа Date выводятся с использованием краткого формата даты, установленного для компьютера. Значения времени выводятся в установленном 12-часовом или 24-часовом формате.
При преобразовании других числовых типов данных к типу Date целая часть числа представляет значение даты, а дробная значение времени. Полночь представляется значением 0, а полдень значением .5. Отрицательные целые числа представляют даты до 30 декабря 1899 г."
ANSI SQL Date кодируется строкой вида YYYY-MM-DD, используй этот формат. MS DAO не пробовал гонять? Он прикольный )30.03.15 13:39 Автор: HandleX <Александр М.> Статус: The Elderman
С DAO сталкивался давным-давно, но не помню почему - на ODBC остановился. Я разные форматы даты пытался скормить Access'у. В том числе и такой:
INSERT INTO [User] ( id, date)
VALUES (1, #2014-02-02#);
Но он даже сохранять такой запрос не хочет, говоря, что допущена ошибка синтаксиса в операторе INSERT
Я фигню тебе написал сорри, не DAO, ADO конечно же, ActiveX Data Objects.30.03.15 18:03 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 30.03.15 18:05 Количество правок: 2
> форматы даты пытался скормить > Access'у. В том числе и такой: > INSERT INTO [User] ( id, date) > VALUES (1, #2014-02-02#); Subj, а поскольку ActiveX, то соответственно, работает преотлично в любом языке/среде программирования, работающем с ActiveX, хоть в IE на JavaScript'e ;), не говоря уже про VB скрипты в продуктах MS. В С/С++ тоже можно каэшь, типа микроскопом гвозди позабивать ))
> Но он даже сохранять такой запрос не хочет, говоря, что > допущена ошибка синтаксиса в операторе INSERT А зачем символами решётки обрамляешь? Заключи в кавычки, например. Ну и про экранирование Den всё правильно тебе пишет...
Символы решетки - чисто Access'овская фишка. Синтаксис такой...31.03.15 00:37 Автор: Den <Денис Т.> Статус: The Elderman
Den, спасибо – полезная информация по SQLPrepare. HandleX, я и с решётками и без них в разной комбинации кавычек пробовал – всё равно ошибка получается. Даже в самом Access когда вручную запрос пишу. Спасибо конечно, но вы сами пробовали подобные запросы Access’у скармливать? Мне так и не удалось правильный формат передачи ему даты найти (((
Если мне не изменяет память, Access функция CDate умеет...01.04.15 10:17 Автор: Den <Денис Т.> Статус: The Elderman Отредактировано 01.04.15 14:49 Количество правок: 2
Если мне не изменяет память, Access функция CDate умеет прожевывать формат даты ISO 8601:
yyyy-mm-dd[Thh:mm:ss[.mmm]], где 'T' - признак начала значения времени.
Соответственно, тебе ничто не мешает использовать в SQLPrepare запрос вида: "INSERT INTO User (id, date) VALUES (?, CDate(?))" и закинуть в этот запрос дату в виде строки формата ISO 8601 через SQLBindParameter.
[updated!] К сож., не могу помочь — на всех моих компах нет Access, дистриб офиса без него.31.03.15 14:19 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 31.03.15 14:48 Количество правок: 3