Альтернатива для курсора

Я бы сделал:

var err = [fetch('index.html').then((success) => { return Promise.resolve(success); }).catch((e) => { return Promise.resolve(e); }),
fetch('http://does-not-exist').then((success) => { return Promise.resolve(success); }).catch((e) => { return Promise.resolve(e); })];

Promise.all(err)
.then(function (res) { console.log('success', res) })
.catch(function (err) { console.log('error', err) }) //never executed
5
задан Z.Szymon 31 March 2019 в 00:10
поделиться

1 ответ

Есть несколько хитростей, чтобы предотвратить ненужное повторное выполнение Oracle. Эта тема сложна, потому что 99,9% времени мы зависим от Oracle, чтобы автоматически переписать запросы для оптимальной работы. Остановка этих оптимизаций не должна быть обычной задачей.

Теоретически, нет способа гарантировать порядок операций декларативного оператора SQL. На практике есть два простых метода, которые могут помочь предотвратить повторный запуск функций: скалярное кеширование подзапроса и ROWNUM.

Во-первых, позвольте мне попытаться воспроизвести проблему. Ссылка на одно значение возвращает три разных числа.

create or replace function function_invocation return number is
begin
    return dbms_random.value;
end;
/

SELECT RESULT value1,
       RESULT value2,
       RESULT value3
  FROM (SELECT function_invocation() RESULT
          FROM dual);

VALUE1   VALUE2   VALUE3
------   ------   ------
0.3089   0.7103   0.2885

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

select result value1, result value1, result value1
from
(
    select (select function_invocation() from dual) result from dual
);

VALUE1   VALUE2   VALUE3
------   ------   ------
0.2450   0.2450   0.2450

В качестве альтернативы, мы можем предотвратить оптимизационные преобразования, добавив псевдостолбец ROWNUM:

SELECT RESULT value1,
       RESULT value2,
       RESULT value3
  FROM (SELECT function_invocation() RESULT, rownum
          FROM dual);

VALUE1   VALUE2   VALUE3
------   ------   ------
0.1678   0.1678   0.1678

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

0
ответ дан Jon Heller 31 March 2019 в 00:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: