Игнорирование обновлений в SQL Server 2005

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

Мой окончательный ответ см. Ниже: В MySQL я решаю эту проблему, выполняя UPDATE IGNORE. Как заставить это работать в SQL Server 2005? Подзапрос использует объединение четырех таблиц, чтобы найти данные для вставки, если они существуют. Обновление выполняется для таблицы, которая может иметь более 90 000 записей, поэтому мне нужно решение, использующее SQL, вместо того, чтобы программа Java, запрашивающая базу данных, извлекала результаты, а затем обновляла те поля, где у нас есть ненулевые значения.

Обновление: мой запрос:

UPDATE #SearchResults SET geneSymbol = (
    SELECT TOP 1 symbol.name FROM 
        GeneSymbol AS symbol JOIN GeneConnector AS geneJoin 
            ON symbol.id = geneJoin.geneSymbolID
        JOIN Result AS sSeq ON geneJoin.sSeqID = sSeq.id 
        JOIN IndelConnector AS joiner ON joiner.sSeqID = sSeq.id 
    WHERE joiner.indelID = #SearchResults.id ORDER BY symbol.id ASC)
WHERE isSNV = 0

Если я добавлю «И имя_символа НЕ НУЛЕВОЕ» в ГДЕ, я получу ошибку SQL. Если я запускаю его как есть, я получаю ошибки «добавление нуля в ненулевой столбец». :-(

Всем спасибо, нашел вот это:

UPDATE #SearchResults SET geneSymbol = 
    ISNULL ((SELECT TOP 1 symbol.name FROM 
        GeneSymbol AS symbol JOIN GeneConnector AS geneJoin 
            ON symbol.id = geneJoin.geneSymbolID
        JOIN Result AS sSeq ON geneJoin.sSeqID = sSeq.id 
        JOIN IndelConnector AS joiner ON joiner.sSeqID = sSeq.id 
    WHERE joiner.indelID = #SearchResults.id ORDER BY symbol.id ASC), ' ')
WHERE isSNV = 0

Хотя было бы лучше ничего не делать в нулевом случае (поэтому я попытаюсь понять другие ответы и посмотреть, быстрее ли они), установка пустого ответа в нулевых случаях также работает, и вот что это делает.

Примечание. Обтекание ISNULL (...) с помощью () приводит к действительно неясным (и неправильным) ошибкам.

ТИА,

Грег


person Greg Dougherty    schedule 16.03.2011    source источник
comment
можно поточнее? У вас есть предложение where в операторе обновления, где вы можете отфильтровать пустые строки, и вы можете ссылаться на обновленную таблицу в соединении, используемом для обновления.   -  person luckyluke    schedule 16.03.2011
comment
У вас есть предложение where в операторе обновления, где вы можете отфильтровать пустые строки. Как? Я вставлю свое соединение ниже, но я не вижу способа отфильтровать NULL внутри него, а TSQL не позволит мне отфильтровать NULL за его пределами.   -  person Greg Dougherty    schedule 16.03.2011
comment
Этот RBAR, кстати, вам следует избегать этого   -  person luckyluke    schedule 16.03.2011


Ответы (2)


with UpdatedGenesDS (
select joiner.indelID, name, row_number() over (order by symbol.id asc) seq
from
GeneSymbol AS symbol JOIN GeneConnector AS geneJoin 
            ON symbol.id = geneJoin.geneSymbolID
        JOIN Result AS sSeq ON geneJoin.sSeqID = sSeq.id 
        JOIN IndelConnector AS joiner ON joiner.sSeqID = sSeq.id 
WHERE name is not null ORDER BY symbol.id ASC
)
update Genes
set geneSymbol = upd.name
from #SearchResults a 
inner join UpdateGenesDs upd on a.id = b.intelID
where upd.seq =1 and isSNV = 0

это полностью обрабатывает нуль, поскольку все они отфильтровываются предикатом where (также можно отфильтровать предикатом соединения, если хотите. Это то, что вы ищете?

person luckyluke    schedule 16.03.2011
comment
Я не знаю. Можно ли это выполнить как SQL? Потому что я искал в MSDN UpdateDataSet SQL Server и с помощью UpdateDataSet фактические примеры использования этого в SQL и не могу найти ни одного. - person Greg Dougherty; 16.03.2011
comment
Это прекрасно работает. Это называется общим табличным выражением. Этот код является законным - person luckyluke; 16.03.2011
comment
@Greg - UpdateDataSet - это имя, которое Люк выбрал для своего Common Table Expression (CTE). Поэтому неудивительно, что вы не можете найти ссылки на него в MSDN. - person Damien_The_Unbeliever; 16.03.2011
comment
Я отредактировал ответ, чтобы он больше походил на пример, а не на фрагмент. - person luckyluke; 16.03.2011
comment
Отредактировано один раз снова. Это должно соответствовать вашим потребностям - person luckyluke; 16.03.2011

Вот еще один вариант, при котором будут обновлены только те строки в #SearchResults, которые успешно объединены. Если в базовых данных нет нулевых значений, то внутренние соединения не будут извлекать нулевые значения, и вам не придется беспокоиться об их фильтрации.

UPDATE #SearchResults
 set geneSymbol = symbol.name
 from #SearchResults sr
  inner join IndelConnector AS joiner
   on joiner.indelID = sr.id
  inner join Result AS sSeq
   on sSeq.id = joiner.sSeqID
  inner join GeneConnector AS geneJoin
   on geneJoin.sSeqID = sSeq.id
  --  Get "lowest" (i.e. first if listed alphabetically) value of name for each id
  inner join (select id, min(name) name
               from GeneSymbol
               group by id) symbol
   on symbol.id = geneJoin.geneSymbolID     
 where isSNV = 0  --  Which table is this value from?

(Могут быть некоторые проблемы с синтаксисом, без таблиц я не могу его отладить)

person Philip Kelley    schedule 16.03.2011
comment
isSNV из #SearchResults (это битовый флаг. Мне нужно использовать другую таблицу для первого соединения, если isSNV равно 1). Хотя ваша идея хороша, она, к сожалению, не работает. Проблема в том, что в GeneConnector может быть несколько записей с одним и тем же sSeqID, но с разными geneSymbolIds (в ​​этом весь смысл таблицы, чтобы у Result был список связанных генов). Все, что делает ваш внутренний выбор, — это воссоздание таблицы GeneSymbol (у нее уже есть только одно имя для каждого идентификатора). Поэтому, когда он сталкивается с идентификатором, который будет содержать несколько GeneSymbols, он терпит неудачу. - person Greg Dougherty; 16.03.2011