Вопрос о вставке / обновлении строк с помощью SQL Server (ASP.NET MVC) - PullRequest
0 голосов
/ 15 июня 2010

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

UPDATE Stats SET Visits=@val WHERE ... a lot of conditions ... AND Date=@Today

Но что, если строка не существует? Я должен был бы использовать

INSERT INTO Stats (...) VALUES (Visits=@val, ..., Date=@Today)

Как я могу проверить, существует строка или нет? Есть ли способ отличаться от COUNT (*)?

Если бы я заполнил таблицу пустыми ячейками, потребовались бы сотни тысяч строк, занимающих мегабайты и не сохраняющих данные.

Ответы [ 4 ]

2 голосов
/ 15 июня 2010

Если вы используете SQL Server 2008 и более поздние версии, вам также следует изучить оператор MERGE, представленный в версии 2008.

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

Я бы попробовал ОБНОВИТЬ, тогда, если @@ ROWCOUNT = 0, попробуйте ВСТАВИТЬ

UPDATE Stats SET Visits=@val WHERE ... a lot of conditions ... AND Date=@Today
IF @@ROWCOUNT = 0
   INSERT INTO Stats (...) VALUES (Visits=@val, ..., Date=@Today)

Или попробуйте ВСТАВИТЬ в TRY / CATCH, а затем ОБНОВИТЬ, если это не удалось.

Я бы не стал сначала тестировать

0 голосов
/ 15 июня 2010

К сожалению, в SQL Server нет какой-либо команды «INSERT OR UPDATE» (о которой я знаю), как в некоторых движках БД.Это означает, что вы должны сначала проверить строку или поймать ошибку, как рекомендуют другие ответы.Надеемся, что у вашей строки есть искусственный первичный ключ, так что вы могли бы сначала запросить этот ключ, используя все условия WHERE, а затем, если строка возвращается, сделать UPDATE ... WHERE key = ..., в противном случае сделать INSERT.Таким образом, вы не выполняете весь запрос дважды.

0 голосов
/ 15 июня 2010

В этих случаях я обычно выполняю следующее (псевдокод, так как сам являюсь человеком DB2):

try:
    INSERT
catch already-exists:
    try:
        UPDATE
    catch anything:
        generate error

Вы можете сделать это в обратном порядке, если у вас больше шансов, чем строк:

try:
    UPDATE
catch not-there:
    try:
        INSERT
    catch anything:
        generate error

Вы никогда не тестируете сначала в СУБД, поскольку база данных может меняться между вами между тестом и выполнением (принцип "лучше попросить прощения, чем обратиться за разрешением").

...