Подтвердить что ты не робот

SQL UPDATE порядок оценки

Каков порядок оценки в следующем запросе:

UPDATE tbl SET q = q + 1, p = q;

То есть, будет ли "tbl"."p" установлено значение q или q + 1? Является ли порядок оценки здесь стандартом SQL?

Спасибо.

UPDATE

После рассмотрения ответа Мигса я провел несколько тестов на всех найденных DB. Хотя я не знаю, что говорит стандарт, реализации меняются.

Учитывая

CREATE TABLE tbl (p INT NOT NULL, q INT NOT NULL);
INSERT INTO tbl VALUES (1, 5);   -- p := 1, q := 5
UPDATE tbl SET q = q + 1, p = q;

Я нашел значения "p" и "q":

database           p   q
-----------------+---+---
Firebird 2.1.3   | 6 | 6  -- But see "Update 2" below
InterBase 2009   | 5 | 6
MySQL 5.0.77     | 6 | 6  -- See "Update 3" below
Oracle XE (10g)  | 5 | 6
PostgreSQL 8.4.2 | 5 | 6
SQLite 3.3.6     | 5 | 6
SQL Server 2016  | 5 | 6

ОБНОВЛЕНИЕ 2

Firebird 2.5 изменяет свое поведение, чтобы соответствовать большинству других SQL-процессов, которые я тестировал, оставив только MySQL. Соответствующая запись Notes Notes, "Логическое изменение в SET SET" , настоятельно предлагает, чтобы поведение большинства было правильным в отношении спецификаций SQL.

Я прослушивал MySQL, чтобы прокомментировать это поведение (ошибка 52861), поскольку они кажутся outlier.

ОБНОВЛЕНИЕ 3

Вышеупомянутая ошибка сегодня (2010-05-19) закрыта, а документация настроена для обновления, чтобы сделать это поведение явным как в описании UPDATE, так и в разделе "Различия в стандартном SQL".

Браво, MySQL.

4b9b3361

Ответ 1

MySQL делает оценку "слева направо" и "видит" новые значения. (Протестировано в версии 5.0.45-community-nt-log MySQL Community Edition)

Кроме того, из руководства MySQL: "Назначения UPDATE с одной таблицей обычно оцениваются слева направо. Для обновлений с несколькими таблицами нет никакой гарантии, что назначения выполняются в любом конкретном порядке".

Теперь "вообще" довольно неопределенно и "нет гарантии" очень плохо, учитывая, что порядок оценки важен.

Итак, чтобы ответить на вопрос: "Является ли поведение, указанное" стандартом SQL ", или это просто соглашение?


UPDATE: удержаться от спецификаций SQL92, которые указаны в элементе "13.10 update statement: search" item "6). (выражение значения) s эффективно оценивается для каждой строки T перед обновлением любой строки T."

IMHO не совсем однозначно, но достаточно, чтобы считать, что СТАНДАРТ НЕ "видеть" результаты вашего собственного обновления. Учитывая ваш пример, как это делают Oracle, PostgreSQL и Interbase.

Ответ 2

UPDATE не видит результатов своей работы.

p будет установлен на q по умолчанию перед обновлением.

Следующий код просто заменит столбцы:

DECLARE @test TABLE (p INT, q INT)

INSERT
INTO    @test
VALUES  (2, 3)

SELECT  *
FROM    @test

p    q
---  ---
  2    3

UPDATE  @test
SET     p = q,
        q = p

SELECT  *
FROM    @test

p    q
---  ---
  3    2

Ответ 3

Запись в таблицу должна произойти после того, как транзакция прошла успешно, когда чтение было завершено.