Nano Hash - криптовалюты, майнинг, программирование

Oracle: Как реализовать *почти* детерминированную функцию?

У меня есть проект, который, по сути, представляет собой пакет вычислений. Это зависит от нескольких параметров, которые, хотя и не являются константами (они могут меняться со временем), не могут измениться в пакетном контексте.

Чтобы было понятно, подумайте о ставке НДС: она может меняться со временем, но когда кто-то закрывает отчетный период, она ведет себя как константа в том, что касается самого закрытия.

Поскольку эти параметры находятся повсюду, я хотел бы найти способ максимально ограничить поиск в БД. В идеале я бы реализовал ДЕТЕРМИНИСТИЧЕСКУЮ функцию, но об этом не может быть и речи - как это предлагается в соответствующей документации.

Есть идеи/предложения?

Заранее спасибо.

РЕДАКТИРОВАТЬ: Имейте также в виду, что эти значения хранятся в базе данных, так как мы можем сохранить ставку НДС, чтобы мы могли знать ее значение в данный момент времени. Хотя это и не ожидается, но возможно, что пакет, относящийся к какому-то предыдущему периоду, будет запущен снова - и ему потребуется знать значение его параметров, какими они были тогда.

Преимущество функции DETERMINISTIC заключается в том, что, учитывая тот факт, что она дает согласованные результаты (один и тот же ввод всегда дает один и тот же результат), я бы сделал, если бы эти значения были константами, и я не хотел бы отслеживать их. Но в документации четко указано, что если функция выполняет поиск в БД, она никогда не должна быть ДЕТЕРМИНИСТИЧЕСКОЙ.

13.11.2013

  • Предложено относительной документацией? Что ты имеешь в виду? Вы можете создать пакет с функцией get_parameter, которая будет возвращать значение. Таким образом, когда вы захотите изменить возвращаемое значение, вы не сделаете недействительными объекты, зависящие от этой функции, потому что перекомпиляция тела пакета этого не вызывает. 13.11.2013
  • Я изменил его, надеюсь, теперь это имеет больше смысла. Ваше предложение интересно, но на самом деле значение ищется в базе данных. Другими словами, требуется, чтобы эти значения были изменены в форме, и я считаю рискованным динамическое создание тел пакетов. 13.11.2013
  • Таким образом, в основном вы хотите иметь значение, которое может иметь разные значения с течением времени. Итак, изменение возможно. Что вы хотите, так это запретить изменение значения, которое больше не является актуальным (это для предыдущего периода), или даже для текущего периода. Вы можете создать триггер, который не позволяет обновлять этот столбец, и вы можете написать функцию (лучше всего в пакете), которая будет запрашивать таблицу и возвращать значение для любого заданного периода (я полагаю, что период здесь будет параметром). Это сработает для вас? Ведь вы никогда не будете уверены, что кто-то не будет возиться с данными за вашей спиной. 13.11.2013
  • Не совсем. Я могу быть уверен, что никто не будет возиться с параметрами во время пакетного запуска (но ваша идея имеет смысл, и, возможно, мне все равно следует ее реализовать). Я просто пытаюсь избежать поиска в базе данных. Вы можете себе представить, что любой из этих параметров будет умножаться примерно в 100 000 раз в одном запросе. Могу ли я положиться на Oracle, чтобы кэшировать его значение? 13.11.2013

Ответы:


1

Вы не можете создать "почти" детерминированную функцию. Вы можете создать детерминированную функцию, если правильно ее вызовете. Если мы предполагаем, что вы создаете простую функцию для расчета суммы НДС, вы можете сделать это двумя способами; во-первых, ссылаясь на таблицу непосредственно в функции:

create or replace function calculate_vat is ( 
       P_Sale_Value in number ) return number is

   l_vat number;

begin

   select trunc(vat_rate * P_Sale_Value, 2) into l_vat
     from vat_table
    where ...

   return l_vat;

end;
/

Это будет называться примерно так:

select sale_value, calculate_vat(sale_value)
  from sales_table

Вы не можете создать эту функцию как детерминированную, поскольку значение в таблице может измениться. Как сказано в в документации:

Не указывайте это предложение, чтобы определить функцию, которая использует переменные пакета или обращается к базе данных любым способом, который может повлиять на возвращаемый результат функции.

Однако вы можете создать функцию по-другому, если передадите значение НДС в качестве параметра:

create or replace function calculate_vat is ( 
       P_Sale_Value in number
     , P_VAT_Rate in number
       ) return number deterministic is

begin    
   return trunc(P_VAT_Rate* P_Sale_Value, 2);    
end;
/

Затем вы можете вызвать его с помощью JOIN в таблице НДС, чтобы получить вашу действительную детерминированную функцию.

select s.sale_value, calculate_vat(s.sale_value, v.vat_rate)
  from sales_table s
  join vat_table v
    on ...
 where ...
13.11.2013
  • Ну, это то, чего я хотел бы избежать, потому что, скорее всего, условие JOIN для таблицы VAT будет выглядеть как 'nvl(vat.end_date,sysdate+1) › sysdate', что, в свою очередь, может иметь значительное негативное влияние на производительность. Я знаю, что не могу использовать детерминированную функцию. То, что я ищу, это способ написать функцию get_vat, которая в идеале будет вести себя как детерминированная. 13.11.2013
  • Условие соединения не должно иметь отрицательной производительности, оно в любом случае будет лучше, чем выполнение отдельных поисков. Я только что дал вам один способ @theodojo... другой способ - это кэширование подзапроса или глобальные переменные. 13.11.2013
  • Это то, что я искал. Я предполагаю, что кэширование подзапросов будет работать и с предложением WITH? 13.11.2013
  • Да, это будет @theodojo. 13.11.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..