Причина, по которой это не работает, заключается в том, что тело оператора DO
на самом деле является строкой, текстом. См. Ссылку
$$
- это просто еще один способ разделения текста в postgresql. Его также можно заменить на '
или $somestuff$
.
Поскольку это строка, у Npgsql и Postgresql нет причин связываться с @value1
.
* Решения 1015 *? Только очень уродливый, поэтому не используйте эту конструкцию, так как вы не можете передать ей какие-либо значения. Работа с конкатенацией строк ничем не отличается от конкатенации в C #.
Альтернативы ? Да!
Вам не нужно обрабатывать исключения в блоках plpgsql. Просто вставьте, используйте ON CONFLICT DO NOTHING
и будьте в пути.
INSERT INTO Foo (Field1,Field2,Field3)
VALUES (@value1,@value2,@value3)
ON CONFLICT DO NOTHING;
select *
from Foo
where Field1 = @value1
and Field2 = @value2;
Или, если вы действительно хотите продолжать использовать plpgsql , вы можете просто создать временную таблицу , используя опцию ON COMMIT DROP
, заполните ее эти параметры в виде одной строки, затем используйте их в операторе DO
. Для этого весь ваш код должен выполняться как часть одной транзакции . Вы можете использовать один явно на всякий случай.
Единственный способ передать параметры в код plpgsql - использовать эти 2 метода:
- Объявление функции с последующим вызовом с аргументами
- Когда вы уже находитесь внутри блока plpgsql, вы можете позвонить:
EXECUTE $$ INSERT ... VALUES ($1, $2, $3); $$ USING 3, 'text value', 5.234;
Конечные ноты:
Как один из разработчиков T-SQL, который любил его свободу, но перешел на Postgresql, я должен сказать, что большая разница в том, что с одной стороны есть T-SQL, который дает мощность, а с другой стороны, это очень мощный Postgresql-ароматизированный SQL. plpgsql очень редко гарантируется. Фактически, в кодовой базе мегабайтов сложных SQL-программ я могу переписать практически каждый код plpgsql в SQL. Вот насколько он действительно мощен по сравнению с SQL на основе MSSQL. Нужно просто привыкнуть и подружиться с очень обширной документацией. Удачи!