у меня есть стол под названием книга
CREATE TABLE book
(
id smallint NOT NULL DEFAULT 0,
bname text,
btype text,
bprices numeric(11,2)[],
CONSTRAINT key PRIMARY KEY (id )
)
и функция save_book
CREATE OR REPLACE FUNCTION save_book(thebook book)
RETURNS text AS
$BODY$
DECLARE
myoutput text :='Nothing has occured';
BEGIN
update book set
bname=thebook.bname,
btype=thebook.btype,bprices=thebook.bprices WHERE id=thebook.id;
IF FOUND THEN
myoutput:= 'Record with PK[' || thebook.id || '] successfully updated';
RETURN myoutput;
END IF;
BEGIN
INSERT INTO book values(thebook.id,thebook.bname,thebook.btype,
thebook.bprices);
myoutput:= 'Record successfully added';
END;
RETURN myoutput;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
теперь, когда я вызываю функцию
SELECT save_book('(179,the art of war,fiction,{190,220})'::book);
я понял ошибку
ERROR: malformed array literal: "{190"
SQL state: 22P02
Character: 18
я не понимаю, потому что я не вижу ошибок в формате массива, любая помощь?
ave_book((179,the art of war,fiction,'{190,220}')::book
. Построенный ряд не нуждается в кавычках.ERROR: syntax error at or near "art"
ave_book((179, 'the art of war', 'fiction', '{190,220}')::book
, как сказал Андрей.Ответы:
Такие вещи становятся сложными. Я работаю над некоторыми смежными проектами прямо сейчас. Основной трюк заключается в том, что PostgreSQL использует формат, который использует двойные кавычки внутри в представлении кортежа для представления литеральных значений, поэтому:
должно сработать. По сути, уловка заключается в создании CSV и заключении в идентификаторы кортежей или массивов. Большая проблема в том, что вам приходится иметь дело с побегом (удваивать кавычки на каждом уровне по мере необходимости). Таким образом, следующее в точности эквивалентно:
Второй подход заключается в использовании конструктора строк:
Первое решение имеет очевидное преимущество, заключающееся в возможности использовать существующие программные среды для генерации и выхода из CSV. Второй самый чистый в SQL. Они могут быть смешаны и сопоставлены.
источник
Если вы когда-нибудь задумывались о правильном синтаксисе для типа строки, спросите Postgres. Следует знать:
Который вернет текстовое представление вашей строки в правильном формате:
Значения столбцов представлены в виде списка без кавычек, разделенного запятыми, заключенного в паретезы.
Двойные кавычки используются вокруг значений, если возможна неоднозначность, включая текст с пробелами. Хотя в данном конкретном случае двойные кавычки
"the art of war"
необязательны, двойные кавычки"{190,220}"
необходимы для массива.Заключите строку в одинарные кавычки, измените и проверьте:
Функция рассмотрена
Рассмотрим то, что мы обсуждали в связанном, предыдущем вопросе:
проблема с составным типом в функции UPSERT
Отдельный блок (
BEGIN .. END;
) только полезно , если вы хотите , чтобы поймать рейз может. Поскольку блок с исключением несет некоторые накладные расходы, имеет смысл иметь отдельный блок, который никогда не может быть введен:EXCEPTION
INSERT
Остальное упростить :
Я также упростил ваше
INSERT
утверждение. Можно безопасно пропустить список столбцов из INSERT при данных обстоятельствах.источник
Хотя я не вижу реального преимущества вашего решения, я имею в виду передачу строки функции вместо передачи отдельных значений, как в
В любом случае, ваше решение также работает, если вы правильно вызываете функцию:
То есть выражение записи не нуждается в кавычках, в то время как текстовые значения и литерал массива нужны.
источник