Форма все еще отправлена даже при том, что функция слушателя возвращает false

Во время компиляции и выполнения запросов SQL Server не тратит время на выяснение того, изменит ли оператор UPDATE какие-либо значения или нет. Он просто выполняет запись, как ожидалось, даже если в этом нет необходимости.

В сценарии, подобном

update table1 set col1 = 'hello'

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

Если мы хотим избежать накладных расходов на эти записи, когда в этом нет необходимости, мы должны разработать способ проверки необходимости обновления. Одним из способов проверки необходимости обновления было бы добавить что-то вроде «where col <> 'hello”.

update table1 set col1 = 'hello' where col1 <> 'hello'

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

Но есть гораздо лучшая альтернатива, использующая сочетание предложения EXISTS с предложением EXCEPT. Идея состоит в том, чтобы сравнить значения в строке назначения со значениями в соответствующей исходной строке, чтобы определить, действительно ли необходимо обновление. Посмотрите на измененный запрос ниже и изучите дополнительный фильтр запросов, начинающийся с EXISTS. Обратите внимание, что внутри предложения EXISTS операторы SELECT не имеют предложения FROM. Эта часть особенно важна, потому что это только добавляет дополнительное постоянное сканирование и операцию фильтрации в плане запроса (стоимость обоих тривиальна). Таким образом, в итоге вы получите очень легкий метод определения того, требуется ли вообще ОБНОВЛЕНИЕ, во-первых, избегая ненужных накладных расходов на запись.

update table1 set col1 = 'hello'
/* AVOID NET ZERO CHANGES */
where exists 
    (
    /* DESTINATION */
    select table1.col1
    except
    /* SOURCE */
    select col1 = 'hello'
    )

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

Более полным примером может быть

update table1
   set col1 = 'hello',
       col2 = 'hello',
       col3 = 'hello'
/* Only update rows from CustomerId 100, 101, 102 & 103 */
where table1.CustomerId IN (100, 101, 102, 103)
/* AVOID NET ZERO CHANGES */
  and exists 
    (
    /* DESTINATION */
    select table1.col1
           table1.col2
           table1.col3
    except
    /* SOURCE */
    select z.col1,
           z.col2,
           z.col3
      from #anytemptableorsubquery z
     where z.CustomerId = table1.CustomerId
    )
7
задан 8 June 2009 в 23:12
поделиться

3 ответа

Объединил информацию из двух очень полезных ответов в решение, которое работает как на Mac, так и на ПК:

<script>
var code = function (eventObject) {
    if (eventObject.preventDefault) {
        eventObject.preventDefault();
    } else if (window.event) /* for ie */ {
        window.event.returnValue = false;
    }
    return true;
};
var element = window.document.getElementById("form");
if (element.addEventListener) {
    element.addEventListener("submit", code, false);
} else if (element.attachEvent) {
    element.attachEvent("onsubmit", code);
}
</script>
8
ответ дан 6 December 2019 в 12:53
поделиться

Я думаю, что вам нужен метод preventDefault () интерфейса Event для браузеров, которые его реализуют. Он отменит отправку формы, как вы ожидали: « return false » для.

Подробнее здесь и здесь .

<script type="text/javascript">
 var code = function (evt) {
            if (evt.preventDefault) {
                evt.preventDefault();
            }
            return false;
};
window.onload = function() {
    var element = window.document.getElementById("form");
    if (element.addEventListener) {
        element.addEventListener("submit", code, false);
    }
};
</script>
2
ответ дан 6 December 2019 в 12:53
поделиться

Похоже, если вы измените свою функцию на

var code = function(e) {
    e.preventDefault();
}

It должен делать то, что вы ищете.

источник

6
ответ дан 6 December 2019 в 12:53
поделиться
Другие вопросы по тегам:

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