Member 14362579 Ответов: 2

Сценарий удаления в SQL server работает странно. Данные, которые не должны быть удалены в соответствии с логикой, удаляются.


У меня есть сценарий удаления sql server в SP, как показано ниже:
----------------------------------------------------
DELETE
      rvb
       FROM
           [dbo].['RVB temp tbl$']           rvb
           JOIN [dbo].['Actual RVBReferenced BR$'] rvbBr ON
           rvb.Rid = rvbBr.Rid
       WHERE
           NOT EXISTS (
               SELECT
                   1
               FROM
                   [dbo].[BR$] tmp
               WHERE
                  tmp.[ED#] = rvbBr.id
           )

------------------------------------------------------------
Таблица rvb содержит 225 Rid(Id), а таблица rvbr содержит Rid и sub id, связанные с Rid. Таблица tmp-это главная таблица, содержащая все идентификаторы sub, что означает, что каждый идентификатор sub в rvbr будет находиться в таблице tmp. Приведенный выше сценарий удаления удаляет Rid в таблице rvb, чьи sub Id(присоединяющиеся к rvbr) не находятся в таблице tmp. Но проблема в том, что сценарий удаления удаляет 3 Rid из sub Id, которые присутствуют в таблице tmp, что является странным функционированием.

Может ли кто-нибудь сказать мне, что не так со скриптом удаления?

Что я уже пробовал:

Я пробовал использовать Rtrim и Ltrim перед переменными, думая, что в данных используемых таблиц может быть проблема с пространством, но бесполезно.

phil.o

Замена вашего вопроса бессмысленным содержанием после того, как вам был предоставлен ответ, довольно груба; пожалуйста, не делайте этого.

2 Ответов

Рейтинг:
2

CHill60

Я попытался воссоздать вашу проблему со следующими образцами данных

declare @rvb table (Rid int)
declare @rvbBr table (Rid int, id int)
declare @tmp table (ed int)

insert into @rvb values (1),(2),(3)
insert into @rvbBr values (1,1), (1,2), (2,1), (2,2), (2,3), (3,3)
insert into @tmp values (1),(2)
Я считаю, что вы удалили бы только Rid (1) из @rvb - не Rid (2) из-за записи rvbBr (2, 3) и не (3), потому что единственная запись на rvbBr-это (3,3).

Если я применяю предложение @OriginalGriff к эквиваленту вашего запроса против моего образца, я делаю это
SELECT rvb.*
FROM @rvb rvb 
JOIN @rvbBr rvbBr ON rvb.Rid = rvbBr.Rid 
WHERE 
NOT EXISTS ( SELECT 1 FROM @tmp tmp WHERE tmp.[ED] = rvbBr.id )
Это возвращает 2 и 3 - неверно! Разве это не те самые, которые не должны быть удалены! Если это правда, то у вас есть огромный ключ к тому, что вы могли бы сделать дальше ...
SELECT * FROM @rvb WHERE Rid NOT IN (
SELECT rvb.*
FROM @rvb rvb 
JOIN @rvbBr rvbBr ON rvb.Rid = rvbBr.Rid 
WHERE NOT EXISTS ( SELECT 1 FROM @tmp tmp WHERE tmp.[ED] = rvbBr.id ) )
Хотя, честно говоря, все это начинает выглядеть немного чересчур. Вы, вероятно, могли бы упростить это с помощью соединений. Вот вам закуска на 10 долларов
select * FROM @rvb WHERE Rid IN 
(SELECT rid FROM @rvbBr rvbBr INNER JOIN @tmp tmp ON rvbBr.id = tmp.ed )
Это возвращает 1 и 2, что не совсем правильно, поэтому вам нужно будет сделать больше работы над ним.

Однако, как всегда, на эти вопросы гораздо легче ответить, если вы предоставите примерные данные и ожидаемые результаты


Рейтинг:
0

OriginalGriff

Мы действительно не можем - потому что у нас нет доступа к вашим данным.

Поэтому откройте окно в SSMS и преобразуйте свой запрос в SELECT, используя все то же самое после первого ключевого слова FROM.
Запустите его, и он покажет вам, какие строки он удалит. Если вы ничего не получаете, начните "обрезать" SQL до тех пор, пока не сделаете это, и внимательно посмотрите на свои данные, чтобы выяснить, почему.

Извините, но мы ничего не можем сделать для вас!