|
14.09.2022, 15:57 | #1 |
NavAx
|
Параметры и литералы - разные результаты запросов с датами
На днях обнаружил прекрасное.
Сразу скажу, что это 4ка или 2009. 2012ю заводить не стал - просьба имеющим проверить. Суть в чем - следующий Job выдает разное кол-во записей в зависимости от того, forceliterals в запросе или forceplaceholders. Глюк связан с обработкой дат при их передаче как литералов в выражениях критериев запросов where. Там в качестве вот этой плюс единицы к TransDate (т.е. любому полю типа "дата") получается не один день, как можно ожидать, и как срабатывает при передаче через параметр, а что-то вроде {ts'1901-01-01 00:00:00'} т.е. один ГОД! X++: static void JobSQLDateParamTest(Args _args) { LedgerJournalTrans ljt; ; select //forceliterals forceplaceholders count(recid) from ljt where ljt.Due < ljt.TransDate + 1; info(int642str(ljt.Recid)); }
__________________
Жизнь прекрасна! Если, конечно, правильно подобрать антидепрессанты... Последний раз редактировалось Maximin; 14.09.2022 в 16:15. |
|
14.09.2022, 17:05 | #2 |
Administrator
|
Ну не знаю. Попробовал сделать сравнение с константой (AX2012):
X++: ljt.TransDate < d + 1; Делаю 2 варианта: 1. d = 23.07.2022. Запрос "< d" 2. d = 22.07.2022. Запрос "< d + 1" И forceplaceholders и forceliterals у меня приводит к одинаковому количеству записей. Или я неправильный пример взял?
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 14.09.2022 в 17:13. |
|
18.09.2022, 18:22 | #3 |
Участник
|
Цитата:
То есть, если просто передать ljt.TransDate < d + 1, то из Аксапты уйдет уже вычисленное значение даты. А в примере джоба параметром является как раз не дата, а число. Не знаю как это транслируется на SQL (логичнее, если бы это было DATEADD(dd...), но может там что-то другое), но видимо при forceliterals что-то не то подставляется или по другому сам запрос формируется. |
|
|
За это сообщение автора поблагодарили: sukhanchik (6). |
16.09.2022, 12:13 | #4 |
Участник
|
А какой смысл сводить поле таблицы, участвующей в запросе, к литералу? Другими словами, какое конкретно значение из примерно миллиона записей вы хотите подставить в качестве литерала?
Мне кажется, forceliterals и не будет себя корректно вести в таком случае. Если вам нужна константа, вычислите её заранее и уже затем передайте в запрос с forceliterals.
__________________
// no comments |
|
16.09.2022, 18:39 | #5 |
Участник
|
Ну у меня выдал именно этот джоб на DAX2012 одинаковые значения.
На DAX4:
|
|
19.09.2022, 09:17 | #6 |
Участник
|
Ну чтобы уж закрыть вопрос (по доступным мне версиям).
Фраза Цитата:
На рабочей выдало так же разные результаты, что не удивительно, так как в запросе ничего не поменялось (ну кроме, естественно, появления поля PARTITION). forceplaceholders Код: SELECT COUNT(T1.RECID) FROM LEDGERJOURNALTRANS T1 WHERE (((PARTITION=@P1) AND (DATAAREAID=@P2)) AND (DUE<(TRANSDATE+@P3))) Код: SELECT COUNT(T1.RECID) FROM LEDGERJOURNALTRANS T1 WHERE (((PARTITION=5637144577) AND (DATAAREAID=N''hld'')) AND (DUE<(TRANSDATE+{ts ''1901-01-01 00:00:00.000''}))) |
|
18.09.2022, 19:19 | #7 |
Участник
|
Чуть чуть покопался.
Пока только DAX4, в DAX2012 что-то у меня сейчас поток запросов идет, в выводе профайлера сложно найти нужное. Ну, оказалось, что datediff не используется. При forceplaceholders запрос формируется Код: exec sp_cursorprepexec @p1 output,@p2 output,N'@P1 nvarchar(8),@P2 int', N'SELECT COUNT(A.RECID) FROM LEDGERJOURNALTRANS A WHERE ((DATAAREAID=@P1) AND (DUE<(TRANSDATE+@P2)))' В итоге вроде нормально: TRANSDATE+@P2, где @P2 целое число, дает следующий день (в дате как раз целая часть это дни). При forceliterals запрос Код: exec sp_cursoropen @p1 output, N'SELECT COUNT(A.RECID) FROM LEDGERJOURNALTRANS A WHERE ((DATAAREAID=N''КодКомпании'') AND (DUE<(TRANSDATE+{ts ''1901-01-01 00:00:00.000''})))' Последний раз редактировалось Raven Melancholic; 18.09.2022 в 19:21. |
|
|
За это сообщение автора поблагодарили: sukhanchik (6). |
Теги |
literal, parameters passing, sql |
|
|