AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 14.09.2022, 15:57   #1  
Maximin is offline
Maximin
NavAx
NavAx Club
 
412 / 346 (12) ++++++
Регистрация: 09.10.2002
Адрес: Москва
Параметры и литералы - разные результаты запросов с датами
На днях обнаружил прекрасное.
Сразу скажу, что это 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  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,317 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Ну не знаю. Попробовал сделать сравнение с константой (AX2012):
X++:
ljt.TransDate < d + 1;
, где d задал в виде константы 22.07.2022.
Делаю 2 варианта:
1. d = 23.07.2022. Запрос "< d"
2. d = 22.07.2022. Запрос "< d + 1"

И forceplaceholders и forceliterals у меня приводит к одинаковому количеству записей.
Или я неправильный пример взял?
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 14.09.2022 в 17:13.
Старый 16.09.2022, 12:13   #3  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
А какой смысл сводить поле таблицы, участвующей в запросе, к литералу? Другими словами, какое конкретно значение из примерно миллиона записей вы хотите подставить в качестве литерала?
Мне кажется, forceliterals и не будет себя корректно вести в таком случае.
Если вам нужна константа, вычислите её заранее и уже затем передайте в запрос с forceliterals.
__________________
// no comments
Старый 16.09.2022, 18:39   #4  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Ну у меня выдал именно этот джоб на DAX2012 одинаковые значения.
На DAX4:
  • С forceplaceholders 1 330 483
  • С forceliterals 1 331 648
Старый 18.09.2022, 18:22   #5  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
... Попробовал сделать сравнение с константой (AX2012):
X++:
ljt.TransDate < d + 1;
, где d задал в виде константы 22.07.2022...

...Или я неправильный пример взял?
Я не анализировал подробно, но как понял, проблема не при любом сравнении, а именно когда вот эта d + 1 вычисляется на стороне SQL, как в этом случае, в котором одно поле таблицы сравнивается с другим полем.

То есть, если просто передать ljt.TransDate < d + 1, то из Аксапты уйдет уже вычисленное значение даты. А в примере джоба параметром является как раз не дата, а число. Не знаю как это транслируется на SQL (логичнее, если бы это было DATEADD(dd...), но может там что-то другое), но видимо при forceliterals что-то не то подставляется или по другому сам запрос формируется.
За это сообщение автора поблагодарили: sukhanchik (6).
Старый 18.09.2022, 19:19   #6  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Чуть чуть покопался.
Пока только 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)))'
В значении параметра @P1 идет код компании, в параметре @P2 1 (единица).
В итоге вроде нормально: 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''})))'
А вот тут 1901-01-01 00:00:00.000 это, как и указал Maximin год, а не день.

Последний раз редактировалось Raven Melancholic; 18.09.2022 в 19:21.
За это сообщение автора поблагодарили: sukhanchik (6).
Старый 19.09.2022, 09:17   #7  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Ну чтобы уж закрыть вопрос (по доступным мне версиям).
Фраза
Цитата:
Сообщение от Raven Melancholic Посмотреть сообщение
Ну у меня выдал именно этот джоб на DAX2012 одинаковые значения.
оказалась не совсем корректной. Запускал на DEV, на котором практически нет данных.
На рабочей выдало так же разные результаты, что не удивительно, так как в запросе ничего не поменялось (ну кроме, естественно, появления поля PARTITION).

forceplaceholders
Код:
SELECT COUNT(T1.RECID) 
	FROM LEDGERJOURNALTRANS T1 
	WHERE (((PARTITION=@P1) 
		AND (DATAAREAID=@P2)) 
		AND (DUE<(TRANSDATE+@P3)))
forceliterals
Код:
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''})))
Теги
literal, parameters passing, sql

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Изменить параметры пакетного задания iiipoizone DAX: Функционал 6 22.08.2018 17:19
SimpleQueryBuilder - простой Х++ конструктор читабельных T-SQL запросов Ruff DAX: Программирование 18 04.02.2016 14:15
Параметры для заказа на покупку в разрезе поставщиков Gait DAX: Функционал 20 02.07.2012 10:50
В Стандартной АХ2009 не работает кнопка <Параметры> на диалоге класса унаследованного от RunBaseReport Pustik DAX: Программирование 3 11.05.2011 19:47
Параметры запросов БД CasperSKY DAX: Программирование 3 22.03.2008 19:32

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 07:17.