Использование WHERE НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ ТОП 1 (id) ИЗ таблицы, ГДЕ aaa LIKE @aaa И не возвращает результаты, где без AND это делает - PullRequest
0 голосов
/ 13 января 2020

Я использую программу C# для передачи данных CSV в базу данных SQL Server Express. Я использую следующую строку SQL, чтобы удостовериться, что двойники не введены в базу данных.

"INSERT INTO Transacties (DebetRekening, CreditRekening, Datum, Bedrag, VolgNummer, Munt, Code, Betalingskenmerk, Omschrijving)
    SELECT 
        @DebetRekening, @CreditRekening, @Datum, @Bedrag, @VolgNummer, 
        @Munt, @Code, @Betalingskenmerk, @Omschrijving
    WHERE NOT EXISTS (SELECT TOP 1(TransactieID)
                      FROM Transacties
                      WHERE DebetRekening LIKE @DebetRekening
                        AND CreditRekening LIKE @CreditRekening
                        AND Datum LIKE @Datum
                        AND Bedrag LIKE @Bedrag
                        AND VolgNummer LIKE @VolgNummer
                        AND Munt LIKE @Munt
                        AND Code LIKE @Code 
                        AND Betalingskenmerk LIKE @Betalingskenmerk 
                        AND Omschrijving LIKE @Omschrijving)"

Добавлены разрывы строк, чтобы сделать ее читабельной, это единственная строка в программе.

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

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

Если я опущу все операторы AND примерно так:

"INSERT INTO Transacties
(DebetRekening, CreditRekening, Datum, Bedrag, VolgNummer, Munt, Code, Betalingskenmerk, Omschrijving)
SELECT @DebetRekening, @CreditRekening, @Datum, @Bedrag, @VolgNummer, @Munt, @Code, @Betalingskenmerk, @Omschrijving
WHERE NOT EXISTS
(
SELECT TOP 1(TransactieID)
FROM Transacties
WHERE
DebetRekening LIKE @DebetRekening
)"

Он найдет существующую запись и не введет ее дважды.

Это не зависит от того, какой параметр я использую, пока есть только один. Как только я вхожу в «И», чтобы проверить другое поле, он больше не может найти записи.

Что мне здесь не хватает?

1 Ответ

0 голосов
/ 13 января 2020

Возможно, проблема в значениях NULL. Условие типа Datum LIKE @Datum не выполняется, если любое из значений равно NULL.

Вам необходимо проверить, равны ли оба значения или null: это Концепция нулевого безопасного равенства (для которой SQLServer не является встроенным, в отличие от MySQL, например).

INSERT INTO Transacties(...)
SELECT ...
WHERE NOT EXISTS
(
    SELECT 1
    FROM Transacties
    WHERE
        (DebetRekening IS NULL AND @DebetRekening IS NULL OR DebetRekening = @DebetRekening)
        AND (CreditRekening IS NUL AND @CreditRekening IS NULL OR CreditRekening = @CreditRekening)
        AND ...
)

Примечания:

  • Вы не * требуется 1016 * в подзапросе EXISTS; конструкция EXISTS предназначена для проверки, существует ли что-то , и база данных в основном отбрасывает результаты немедленно. SELECT 1 является широко используемым соглашением

  • a LIKE b эквивалентно a = b (поскольку в правом операнде не используется подстановочный знак): я упростил ваш код соответственно

  • в зависимости от вашей базы данных, лучшие варианты могут существовать. Например, MySQL имеет ON DUPLICATE KEYS, Postgres имеет ON CONFLICT.

...