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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 28.09.2011, 17:36   #1  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5813 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Thumbs down Отключение функциональных индексов для Oracle убрали из ядра AX 2009
Цитата:
Сообщение от gl00mie Посмотреть сообщение
  • Действительно ли можно отключить хинтами использование функциональных индексов для Оракла в AX 2009?
  • Если да, то каким именно хинтом это можно сделать?
  • Где найти описание хинтов для AX 2009?
Я тут на досуге долго э... смотрел в хрустальный шар и увидел там ответы на эти вопросы. Ответы сводятся к тому, что штатно никакими хинтами отключить использование функциональных индексов в AX 2009 уже, в отличие от 3.0, нельзя. Ниже - краткая выжимка того, что удалось разглядеть в хрустальном шаре.
За использование функциональных индексов в ядре отвечают, насколько я смог разглядеть, три функции, чьи настоящие имена удалось-таки недавно узнать: MONOCASE_FIELD(), MONOCASE_LITERAL() и MONOCASE_PLACEHOLDER(). Вот, к примеру, как выглядит псевдокод функции MONOCASE_FIELD() в ax32serv.exe версии 3.0 KR3
X++:
char* MONOCASE_FIELD(char *pszBuf, CSqlFieldInfo *pSqlFieldInfo, bool forceMonoCase)
{
  if (gDatabaseCLI == DatabaseCLI::OCI)
  {
    if (  !forceMonoCase
       || !pSqlFieldInfo
       || ((fnGetSessionInfo()->getSqlSystem()->DatabaseHints >> 14) & 1)
       || ((fnGetSessionInfo()->getSqlSystem()->DatabaseHints >> 15) & 1) 
       )
    {
      strcpy(pszBuf, "%s");
    }
    else
    {
      sprintf(pszBuf, "SUBSTR(%s,1,%i)", "NLS_LOWER(%s)", pSqlFieldInfo->cbStringFieldBufSize - 1);
    }
  }
  else
  {
    if (!forceMonoCase || ((fnGetSessionInfo()->getSqlSystem()->DatabaseHints >> 15) & 1))
    {
      strcpy(pszBuf, "%s");
    }
    else
    {
      strcpy(pszBuf, "{fn LCASE(%s)}");
    }
  }
  return pszBuf;
}
Тут видно, что параметр forceMonoCase (название придумано мной) может быть "перекрыт" хинтом 0x8000 - при его использовании к строковому полю не будут применены никакие дополнительные функции. А теперь как эта же функция выглядит в ax32serv.exe версии 2009 SP1 RU7:
X++:
char* MONOCASE_FIELD(wchar_t *pwszBuf, unsigned int cnBufSize, struSqlFieldInfo *pSqlFieldInfo, bool forceMonoCase)
{
  int len;
  if (sql_dbcli != DatabaseCLI::OCI)
  {
    if (forceMonoCase)
    {
      return StringCchCopyW(pwszBuf, cnBufSize, L"{fn LCASE(%s)}");
    }
    return StringCchCopyW(pwszBuf, cnBufSize, L"%s");
  }
  if (!forceMonoCase || !pSqlFieldInfo)
  {
    return StringCchCopyW(pwszBuf, cnBufSize, L"%s");
  }
  len = pSqlFieldInfo->BaseType == Types::String ? (*&pSqlFieldInfo->cbStringFieldBufSize >> 1) - 1 : 0;
  return StringCchPrintfW(pwszBuf, cnBufSize, L"SUBSTR(%s,1,%i)", L"NLS_LOWER(%s)", len);
}
Все упоминания о хинтах пропали, и определяющим стал параметр forceMonoCase, а этот параметр во всех местах, где вызывается MONOCASE_FIELD(), определяется как
X++:
theDatabase()->DatabaseId == DatabaseId::Oracle
исключение составляет лишь SqlSystem.monocaseFmt() - здесь параметр forceMonoCase по умолчанию равен true, но может принять значение false, если при вызове этого метода указать параметр _considerSystemVariables == true и СУБД окажется НЕ Oracle. Аналогичная картина наблюдается для остальных двух функций. Вот псевдокод функции MONOCASE_LITERAL() в ядре 3.0 KR3
X++:
char* MONOCASE_LITERAL(char *pszBuf, bool forceMonoCase)
{
  if (gDatabaseCLI == DatabaseCLI::OCI)
  {
    if (forceMonoCase && !((fnGetSessionInfo()->getSqlSystem()->DatabaseHints >> 15) & 1))
    {
      return strcpy(pszBuf, "NLS_LOWER(%s)");
    }
  }
  else
  {
    if (forceMonoCase && !((fnGetSessionInfo()->getSqlSystem()->DatabaseHints >> 15) & 1))
    {
      return strcpy(pszBuf, "{fn LCASE(%s)}");
    }
  }
  return strcpy(pszBuf, "%s");
}
А вот она же в ядре 2009 SP1 RU7:
X++:
wchar_t* MONOCASE_LITERAL(wchar_t *pwszBuf, unsigned int cnBufSize, bool forceMonoCase)
{
  if (sql_dbcli != DatabaseCLI::OCI)
  {
    if (forceMonoCase)
    {
      return StringCchCopyW(pwszBuf, cnBufSize, L"{fn LCASE(%s)}");
    }
  }
  else
  {
    if (forceMonoCase)
    {
      return StringCchCopyW(pwszBuf, cnBufSize, L"NLS_LOWER(%s)");
    }  
  }	
  return StringCchCopyW(pwszBuf, cnBufSize, L"%s");
}
Вот MONOCASE_PLACEHOLDER() в ядре 3.0 KR3
X++:
void MONOCASE_PLACEHOLDER(char *pszBuf, void *a2, bool forceMonoCase, char *pszInOutBuf)
{
  // ...
  if (*pszInOutBuf)
  {
    v5 = *a2 + 1;
  }
  else
  {
    v5 = *(a2 + 4) + 1;
  }
  if (gDatabaseCLI == DatabaseCLI::OCI)
  {
    strcpy(pszInOutBuf), *pszInOutBuf ? "in" : "out");
    if (!forceMonoCase || ((fnGetSessionInfo()->getSqlSystem()->DatabaseHints >> 15) & 1))
      sprintf(pszBuf, ":%s%i", &pszInOutBuf, v5);
    else
      sprintf(pszBuf, "NLS_LOWER(:%s%i)", &pszInOutBuf, v5);
  }
  else
  {
    if (!forceMonoCase || ((fnGetSessionInfo()->getSqlSystem()->DatabaseHints >> 15) & 1))
      sprintf(pszBuf, "?");
    else
      sprintf(pszBuf, "{fn LCASE(?)}");
  }
}
И в ядре 2009 SP1 RU7:
X++:
void MONOCASE_PLACEHOLDER(wchar_t *a1, unsigned int *a2, void *pSqlField, void *pSqlMonocaseParamCnt, bool forceMonoCase, bool bIsIn)
{
  int v6;
  wchar_t v12;
  if (bIsIn)
  {
    ++*pSqlMonocaseParamCnt;
    v6 = *pSqlMonocaseParamCnt;
  }
  else
  {
    ++*(pSqlMonocaseParamCnt + 1);
    v6 = *(pSqlMonocaseParamCnt + 1);
  }
  if (sql_dbcli == DatabaseCLI::OCI)
  {
    StringCchCopyW(&v12, 4, bIsIn ? L"in" : L"out");
    StringCchPrintfExW(a1, *a2, &a1, a2, 0, forceMonoCase ? L"NLS_LOWER(:%s%i)" : L":%s%i", &v12, v6);
  }
  else
  {
    StringCchPrintfExW(a1, *a2, &a1, a2, 0, forceMonoCase ? L"{fn LCASE(?)}" : L"?");
  }
}
Таким образом, если в 3.0 (и, возможно, в 4.0 тоже!) существовал штатный, пусть и не документированный, способ отключить использование функциональных индексов при работе с СУБД Oracle, то в 2009-й из ядра его убрали, а все умоминания про такую возможность в конфигурационной утилите и в документаций - просто не подчищенные хвосты.
За это сообщение автора поблагодарили: shred (0), sukhanchik (15), Logger (18), lev (10), S.Kuskov (10).
Теги
ax2009, ax3.0, databasehints, oracle, администрирование, индекс, настройка, полезное, субд

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
mbsturk: Ax 2009 Rollup 4 Version Checker Blog bot DAX Blogs 0 29.04.2010 17:05
DynamicsAxSCM: Sales and purchase prices in relation to the item price setup in Microsoft Dynamics AX 2009 Blog bot DAX Blogs 0 11.02.2010 09:05
emeadaxsupport: List of fixes that improve performance of certain features in Dynamics AX 2009 Blog bot DAX Blogs 0 13.10.2009 19:06
Dynamics AX Sustained Engineering: Dynamics AX 2009 Patching Blog bot DAX Blogs 0 08.10.2008 10:05
axStart: Microsoft Dynamics AX 2009 Hot Topics Web Seminar Series Blog bot DAX Blogs 0 06.08.2008 12:05
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

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

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

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