Если не существует Вставить внутри цикла, запись которого обновлена - PullRequest
0 голосов
/ 24 декабря 2018

Используя SQL Server 2016, у меня есть очень простой IF NOT Exists ..... INSERT statement внутри цикла.Это работает хорошо, как и ожидалось.Есть ли способ определить, какие записи существовали, следовательно, не были вставлены, а какие записи не существовали, поэтому были вставлены без использования второго запроса?

Я могу легко добиться этого, выполнив SELECT, а затем, если не найден, вставляюОднако это два запроса в моем цикле.Я хотел бы попытаться добиться этого в одном запросе, если это возможно?

Цель этого состоит в том, чтобы показать пользователю:

  1. Крис теперь зарегистрирован на английском языке
  2. Крис теперь зачислен в математику
  3. Крис уже зачислен в науку

Таким образом, 1 и 2 не существует, поэтому вставлены.3 существовал, поэтому не вставил

и пример этого цикла для Джона:

    for i = 0 to numOfCourses
        sql = IF NOT EXISTS (SELECT fieldName from tableName 
        WHERE courseID = 1 AND directoryID = 2)
        BEGIN
        INSERT INTO tableName(courseID, directoryID)
        VALUES (1, 2) 
        END 
    next

Ответы [ 2 ]

0 голосов
/ 24 декабря 2018

Вы можете использовать команду MERGE (Transact-SQL) с комбинацией Предложение OUTPUT (Transact-SQL)

Merge выполнит условную вставку и OUTPUT вернет / сохранит вставленные записи.
Затем вы просто сравниваете заданные записи со вставленными и те, которые не существуют во вставленной коллекции, уже существовали в таблице.

DECLARE @InsertedNames AS TABLE (Name VARCHAR(200))
DECLARE @GivenNames AS TABLE (Name VARCHAR(200))
INSERT INTO @GivenNames VALUES ('One'), ('Two')

MERGE INTO TableName AS t  
USING (SELECT Name FROM @GivenNames) AS given (Name)  
    ON t.Name = given.Name  
WHEN NOT MATCHED THEN  
    INSERT (Name) VALUES (given.Name)  
OUTPUT inserted.Name INTO @InsertedNames;

-- return all names with result.
SELECT 'inserted', Name FROM @InsertedNames  
UNION ALL  
SELECT 'already existed', g.Name 
FROM @GivenNames g 
WHERE g.Name NOT IN (SELECT Name FROM @InsertedNames)
0 голосов
/ 24 декабря 2018

@@ ROWCOUNT может оказаться полезным здесь ...

INSERT INTO tableName(courseID, directoryID)
SELECT 1 as courseID, 2 as directoryID 
WHERE NOT EXISTS (SELECT 1 FROM tableName WHERE courseID = 1 AND directoryID = 2);

SELECT CASE WHEN @@ROWCOUNT = 1 
            THEN 'Chris is now enrolled in English'
            ELSE 'Chris was already enrolled in English' END as my_result;

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

Я адаптировал этот ответ от: Как получить количество строк, вставленных транзакцией

Надеюсь, это поможет.

...