Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Select, update, insert в одной процедуре  [new]
Belowzero2
Member

Откуда:
Сообщений: 12
дано: таблица IndexContainer c полями
KeyHash varchar(8) (ключевое поле)
Content varchar(max)

Нужно создать хранимую процедуру
На вход в процедуру подается два параметра:
@KeyHash varchar(8)
@Content varchar(max)

Процедура должна сделать следующее: найти в таблице строку с заданным KeyHash, и если строка существует, к полю Content дописать справа содержимое параметра @Content, иначе добавить новую запись с этими значениями. Все по отдельности понятно, но как передать данные из select в update, не понимаю. Помогите, пожалуйста
22 ноя 12, 22:50    [13516328]     Ответить | Цитировать Сообщить модератору
 Re: Select, update, insert в одной процедуре  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31430
Belowzero2
Все по отдельности понятно, но как передать данные из select в update, не понимаю
Передавать не нужно.

Делаете UPDATE, если строка не обновилась (проверяете по значению переменной @@ROWCOUNT), то делаете INSERT
22 ноя 12, 22:56    [13516346]     Ответить | Цитировать Сообщить модератору
 Re: Select, update, insert в одной процедуре  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74925
Belowzero2,

BOL->MERGE
22 ноя 12, 23:04    [13516362]     Ответить | Цитировать Сообщить модератору
 Re: Select, update, insert в одной процедуре  [new]
Belowzero2
Member

Откуда:
Сообщений: 12
alexeyvg
Делаете UPDATE, если строка не обновилась (проверяете по значению переменной @@ROWCOUNT), то делаете INSERT

Тогда вопрос как обновить: в колонке Content может быть NULL, в этом случае UPDATE .WRITE выдает ошибку, то есть как то бы надо проверить наличие значения перед записью
22 ноя 12, 23:55    [13516444]     Ответить | Цитировать Сообщить модератору
 Re: Select, update, insert в одной процедуре  [new]
dalex1973
Member

Откуда: Польша
Сообщений: 287
MERGE myTable T
USING (SELECT @KeyHash ,@Content) AS S(KeyHash,Content)
ON T.KeyHash=S.KeyHash
WHEN NOT MATCHED THEN INSERT(KeyHash,Content)
VALUES(KeyHash,Content)
WHEN MATCHED THEN UPDATE
SET T.Content = ISNULL(T.Content,'')+S.Content;
23 ноя 12, 00:16    [13516479]     Ответить | Цитировать Сообщить модератору
 Re: Select, update, insert в одной процедуре  [new]
Belowzero2
Member

Откуда:
Сообщений: 12
dalex1973
MERGE myTable T
USING (SELECT @KeyHash ,@Content) AS S(KeyHash,Content)
ON T.KeyHash=S.KeyHash
WHEN NOT MATCHED THEN INSERT(KeyHash,Content)
VALUES(KeyHash,Content)
WHEN MATCHED THEN UPDATE
SET T.Content = ISNULL(T.Content,'')+S.Content;


идеальная конструкция, спасибо. За исключением того, что UPDATE для строк в несколько десятков мегабайт неоптимален, я использую UPDATE.WRITE, а вот он не срабатывает на значение NULL. Бьюсь второй час над этой проблемой
23 ноя 12, 01:39    [13516597]     Ответить | Цитировать Сообщить модератору
 Re: Select, update, insert в одной процедуре  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31430
Belowzero2
За исключением того, что UPDATE для строк в несколько десятков мегабайт неоптимален, я использую UPDATE.WRITE
Странно, не замечал, что UPDATE.WRITE работает быстрее...
Belowzero2
то есть как то бы надо проверить наличие значения перед записью
Можно использовать просто IF EXISTS()

Но ИМХО MERGE лучше, я про него как то не подумал.
23 ноя 12, 09:07    [13516945]     Ответить | Цитировать Сообщить модератору
 Re: Select, update, insert в одной процедуре  [new]
Гость333
Member

Откуда:
Сообщений: 3683
alexeyvg
Belowzero2
то есть как то бы надо проверить наличие значения перед записью
Можно использовать просто IF EXISTS()


При этом нужно обратить внимание на возможную ситуацию, когда две параллельные коннекции одновременно пытаются обработать запись с одним и тем же KeyHash.
Коннекция 1 проверяет, что запись не существует; в это время коннекция 2 тоже видит, что запись не существует; коннекция 1 вставляет новую запись; коннекция 2 также пытается вставить запись и ловит key violation. Извиняюсь, если для топикстартера это очевидный баян :)
23 ноя 12, 10:28    [13517382]     Ответить | Цитировать Сообщить модератору
 Re: Select, update, insert в одной процедуре  [new]
Belowzero2
Member

Откуда:
Сообщений: 12
Гость333,

Коннект всегда один, поэтому сие не происходит. Проблему с UPDATE.WRITE решил просто - Content по умолчанию инициализируется пустым значением
23 ноя 12, 10:38    [13517470]     Ответить | Цитировать Сообщить модератору
 Re: Select, update, insert в одной процедуре  [new]
dalex1973
Member

Откуда: Польша
Сообщений: 287
Belowzero2
идеальная конструкция, спасибо. За исключением того, что UPDATE для строк в несколько десятков мегабайт неоптимален, я использую UPDATE.WRITE, а вот он не срабатывает на значение NULL. Бьюсь второй час над этой проблемой

Update есть Update. Никто не мешает сделать
WHEN MATCHED THEN UPDATE
SET T.Content .WRITE(@Content,NULL,0);


Ваше решение о DEFAULT = '' правильное.
23 ноя 12, 12:44    [13518528]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить