Как объединить несколько операторов выбора, когда они не близко друг к другу? - PullRequest
0 голосов
/ 02 июля 2019

У меня есть запрос sql, который проверяет существование некоторых записей, если эти записи существуют, возникает ошибка для них, иначе вставьте их в базу данных.В моем запросе, так как мне нужно возвращать сообщения об ошибках для каждой записи, мне нужно выбрать несколько пользовательских текстов, проблема в том, что они отображаются в виде отдельных таблиц, а не в одной таблице, которую я хочу (так как я вызываю этот запрос из приложения nodejs)и он возвращает массив для меня, поэтому он возвращает только первую таблицу (сообщение об ошибке) для меня).

Я искал и достигаю этих двух вариантов:
1- Используйте UNION (что не решает моюcase)
2- Вставить все записи в другую таблицу и затем получить все ее записи (что не красиво! :))

DECLARE @errorCOUNT int
SET @errorCOUNT = 0
BEGIN TRANSACTION [Tran1]
IF EXISTS (SELECT * FROM Categories WHERE CategoryName = 'myCat1')
BEGIN
    SELECT 'This is error for is = 4' As err
    SET @errorCOUNT = @errorCOUNT + 1
END
ELSE
BEGIN
    INSERT INTO Categories VALUES ('myCat1')
END
----------------------------
IF EXISTS (SELECT * FROM Categories WHERE CategoryName = 'myCat2')
BEGIN
    SELECT 'This is error for is = 5' AS err
    SET @errorCOUNT = @errorCOUNT + 1
END
ELSE
BEGIN
    INSERT INTO Categories VALUES ('myCat2')
END
----------------------------
IF @errorCOUNT > 0
BEGIN
    ROLLBACK TRANSACTION [Tran1]
END
ELSE 
BEGIN
    COMMIT TRANSACTION [Tran1]
END

What I got (image)

Как я уже говорил, я хочу, чтобы все эти операторы select были показаны в одной таблице, чтобы они возвращались на мой сервер в виде одного массива.
Я просто думаю, что хорошо упомянуть, что мой запрос завершается в цикле, поэтомуон может иметь различное количество IF...ELSE (между --- строками).

Надеюсь, я все понял.Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 02 июля 2019

Попробуйте это, будет работать:

BEGIN TRANSACTION [Tran1]
DECLARE @err AS TABLE ( msg NVARCHAR(MAX) NOT NULL )
DECLARE @errorCOUNT AS INT = 0
IF EXISTS (SELECT * FROM Categories WHERE CategoryName = 'myCat1')
BEGIN
  INSERT INTO @err (msg) VALUES ('This is error for is = 4')
  SET @errorCOUNT = @errorCOUNT + 1
END
ELSE
BEGIN
  INSERT INTO Categories VALUES ('myCat1')
END
IF EXISTS (SELECT * FROM Categories WHERE CategoryName = 'myCat2')
BEGIN
  INSERT INTO @err (msg) VALUES ('This is error for is = 5')
  SET @errorCOUNT = @errorCOUNT + 1
END
ELSE
BEGIN
  INSERT INTO Categories VALUES ('myCat2')
END
IF @errorCOUNT > 0
BEGIN
  SELECT * FROM @err
  ROLLBACK TRANSACTION [Tran1]
END
ELSE 
BEGIN
  COMMIT TRANSACTION [Tran1]
END
1 голос
/ 02 июля 2019

Я не понимаю, что вы действительно хотите там делать, но вот совет, использующий оператор MERGE и предложение OUTPUT, возможно, это то, что вы после

DECLARE @T TABLE(CategoryName VARCHAR(45));

MERGE INTO T
USING (VALUES('MyCat1'), ('MyCat2')) TT(CategoryName)
ON T.CategoryName = TT.CategoryName -- Or <> instead of =
WHEN NOT MATCHED THEN
INSERT VALUES(TT.CategoryName)
OUTPUT TT.CategoryName INTO @T;

SELECT CASE WHEN CategoryName = 'MyCat1'
            THEN 'This is error for is = 4'
            WHEN CategoryName = 'MyCat2'
            THEN 'This is error for is = 5' 
       END Res
FROM @T;

Кроме того, я не думаю, что вам нужна переменная @ErrorCount, поскольку у вас уже есть @@ROWCOUNT, которую вы можете использовать вместо нее.

Вот db <> скрипка , где вы можете увидеть, как она работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...