ОБНОВЛЕНИЕ Таблица SET Поле - PullRequest
2 голосов
/ 10 июня 2010

Это мой самый первый пост! Потерпите меня. У меня есть заявление об обновлении, которое я пытаюсь понять, как SQL Server обрабатывает его.

UPDATE a
    SET a.vField3 = b.vField3
FROM tableName a
    INNER JOIN tableName b on a.vField1 = b.vField1
        AND b.nField2 = a.nField2 – 1

Это мой запрос в его самой простой форме.

vField1 is a Varchar
nField2 is an int (autonumber)
vField3 is a Varchar

Я пропустил предложение WHERE, чтобы понять, что есть логика, которая в противном случае делает это необходимым.

Скажем, vField1 - это номер клиента, и этот клиент имеет 3 записи Значение в nField2 равно 1, 2 и 3 последовательно. vField3 - это статус

Когда обновление доходит до a.nField2 = 1, a.nField2 -1 отсутствует, поэтому оно продолжается Когда обновление доходит до a.nField2 = 2, b.nField2 = 1 Когда обновление доходит до a.nField2 = 3, b.nField2 = 2

Таким образом, когда Обновление находится на a.nField2 = 2, псевдоним b отражает то, что находится на предыдущей строке (b.nField2 = 1) И это Устанавливает значение Varchar a.vField3 = b.vField3

Когда обновление для a.nField2 = 3, псевдоним b отражает то, что находится на предыдущей строке (b.nField2 = 2) И это (должно) УСТАНОВИТЬ значение Varchar a.vField3 = b.vField3

Когда процесс завершен - Вторая из трех записей выглядит так, как ожидалось - поэтому значение в vField3 второй записи отражает значение в vField3 из Первой записи

Однако vField3 из Третьей записи не отражает значение в vField3 из Второй записи.

Я думаю, это демонстрирует, что SQL Server может производить какую-то транзакцию, а затем обновление.

Вопрос: Как я могу получить обновление БД после каждой транзакции, чтобы я мог ссылаться на значения, сгенерированные каждой транзакцией?

Спасибо. davlyo

Ответы [ 2 ]

3 голосов
/ 10 июня 2010

Во-первых, и, самое главное, вы ошибаетесь в своем заблуждении, что транзакция будет логически реализовывать какой-то определенный цикл, потому что ваши записи хранятся «последовательно». На самом деле порядок ваших записей в вашей базе данных undefined , и нет никакого смысла вообще думать о хранении вашей таблицы таким упорядоченным образом. На самом деле вы должны попытаться полностью избавиться от этого, иначе это приведет вас ко всем ловушкам и вредным привычкам. Вместо этого попробуйте логически представить операторы, выполняемые как операции над множествами (в математическом смысле), а не как обходы курсора.

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

Следовательно, для того, чтобы операция UPDATE в реляционной базе данных давала согласованные результаты, любой запрос должен работать как одна транзакция. Транзакция захватывает моментальный снимок записей, которые она будет обновлять, обновляет их согласованным, атомарным образом, а затем применяет результаты обратно к данным. Просто нет логического представления о циклическом выполнении SQL над записями или чем-то еще.

1 голос
/ 10 июня 2010

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

Также имейте в виду, что это самостоятельное соединение, поэтому то, что изначально было второй / третьей записью, не будет после запросазапустить.Одна запись будет «потеряна» - исходная третья запись, и запись со значением 1 будет продублирована.

Например, вы начинаете с: Клиент, aField2, aField3

mdma    1     A
mdma    2     B
mdma    3     C

После запуска обновления значения будут

mdma    1    A
mdma    2    A
mdma    3    B

Это то, что вы видите /ожидая

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...