Синтаксическая ошибка при или около $ 1 при попытке изменить тип в postgreSQL-9.6


0 принят

Возможно, я ошибаюсь, но я думаю, что этого не может быть достигнуто по той же причине, что имя таблицы не может быть передано как параметр запроса.

Однако для этого вы можете использовать замену строки:

ALTER TYPE ... ADD VALUE ...

Пожалуйста, имейте в виду, что это не безопасный подход!

ОБНОВИТЬ:

Другим решением будет использование хранимой процедуры, выполняющей команду. Однако вы не можете просто вызвать pg_enumкоманду внутри процедуры / функции, потому что она не работает внутри блоков транзакций. Вы получите следующую ошибку:

«ALTER TYPE ... ADD невозможно выполнить из функции или строки с несколькими командами»

Этот поток должен пролить свет на проблему: проблемы с манипуляцией типа ENUM в 9.1

Однако может быть решение вашей проблемы. Похоже, вы пытаетесь изменить существующий тип перечисления (добавьте новое значение). Вы можете создать функцию, которая работает -- Also works within transactions in PostgreSQL 9.1+ (but you need -- to reconnect to the database after transaction commit, because -- new enum items are not be visible within the session you used -- to add them). -- -- See http://en.dklab.ru/lib/dklab_postgresql_enum/ -- -- (C) Dmitry Koterov, 2013 -- This code is BSD licensed. -- CREATE SCHEMA enum AUTHORIZATION postgres; SET search_path = enum, pg_catalog; SET check_function_bodies = false; CREATE OR REPLACE FUNCTION enum.enum_add ( enum_name varchar, enum_elem varchar ) RETURNS void AS $body$ DECLARE eoid OID; has_sortorder BOOLEAN; BEGIN eoid := ( SELECT pg_type.oid FROM pg_type JOIN pg_namespace ON pg_namespace.oid=pg_type.typnamespace WHERE typtype='e' AND enum_name IN(typname, nspname||'.'||typname) ); has_sortorder := EXISTS( select 1 from pg_attribute where attrelid=(select oid from pg_class where relname='pg_enum') and attname='enumsortorder' ); IF has_sortorder THEN EXECUTE ' INSERT INTO pg_enum(enumtypid, enumlabel, enumsortorder) VALUES( '||eoid||', '||quote_literal(enum_elem)||', (SELECT MAX(enumsortorder) + 1 FROM pg_enum WHERE enumtypid='||eoid||') ) '; ELSE EXECUTE E'INSERT INTO pg_enum(enumtypid, enumlabel) VALUES('||eoid||', '||quote_literal(enum_elem)||')'; END IF; END; $body$ LANGUAGE 'plpgsql'; COMMENT ON FUNCTION enum.enum_add (enum_name character varying, enum_elem character varying) IS 'Inserts a new ENUM element wthout re-creating the whole type.'; непосредственно в таблице. Набор функций базы данных, предназначенных для манипулирования типами перечислений, можно найти здесь: PostgreSQL 8.3+, 9.1+ ALTER ENUM эмуляция: добавление / удаление элементов, транзакции .

Функция, которая добавляет новое значение в существующее перечисление, выглядит следующим образом:

using (var cmd = connection.CreateCommand())
{
    cmd.CommandText = @"enum.enum_add";
    cmd.Parameters.AddWithValue("enum_name", "attributeName");
    cmd.Parameters.AddWithValue("enum_elem", "O'Reilly");
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.ExecuteNonQuery();
}

Теперь вы можете просто вызвать хранимую процедуру / функцию из своего кода на C #:

ALTER TYPE

Обратите внимание, что вышеуказанная функция не будет работать, если вы попытаетесь добавить существующее значение.


0

У меня нет опыта работы с npgsql, хотя это может быть совершенно неправильно, но NpgsqlCommand, похоже, выполняет подготовленный оператор . Если это так, вы не можете подготовить заявление ALTER:

заявление

Любой оператор SELECT, INSERT, UPDATE, DELETE или VALUES.


0

PostgreSQL везде не поддерживает замещающие параметры, и, если я не ошибаюсь, он специально не поддерживается в операторах DDL, таких как ALTER TYPE. Вероятно, вам нужно будет вставить значение, которое вы хотите в качестве литерала в своем отчете (обязательно учтите SQL-инъекцию).

C #, npgsql, 9,6-PostgreSQL,

c#,npgsql,postgresql-9.6,

0

Ответов: 3


0 принят

Возможно, я ошибаюсь, но я думаю, что этого не может быть достигнуто по той же причине, что имя таблицы не может быть передано как параметр запроса.

Однако для этого вы можете использовать замену строки:

ALTER TYPE ... ADD VALUE ...

Пожалуйста, имейте в виду, что это не безопасный подход!

ОБНОВИТЬ:

Другим решением будет использование хранимой процедуры, выполняющей команду. Однако вы не можете просто вызвать pg_enumкоманду внутри процедуры / функции, потому что она не работает внутри блоков транзакций. Вы получите следующую ошибку:

«ALTER TYPE ... ADD невозможно выполнить из функции или строки с несколькими командами»

Этот поток должен пролить свет на проблему: проблемы с манипуляцией типа ENUM в 9.1

Однако может быть решение вашей проблемы. Похоже, вы пытаетесь изменить существующий тип перечисления (добавьте новое значение). Вы можете создать функцию, которая работает -- Also works within transactions in PostgreSQL 9.1+ (but you need -- to reconnect to the database after transaction commit, because -- new enum items are not be visible within the session you used -- to add them). -- -- See http://en.dklab.ru/lib/dklab_postgresql_enum/ -- -- (C) Dmitry Koterov, 2013 -- This code is BSD licensed. -- CREATE SCHEMA enum AUTHORIZATION postgres; SET search_path = enum, pg_catalog; SET check_function_bodies = false; CREATE OR REPLACE FUNCTION enum.enum_add ( enum_name varchar, enum_elem varchar ) RETURNS void AS $body$ DECLARE eoid OID; has_sortorder BOOLEAN; BEGIN eoid := ( SELECT pg_type.oid FROM pg_type JOIN pg_namespace ON pg_namespace.oid=pg_type.typnamespace WHERE typtype='e' AND enum_name IN(typname, nspname||'.'||typname) ); has_sortorder := EXISTS( select 1 from pg_attribute where attrelid=(select oid from pg_class where relname='pg_enum') and attname='enumsortorder' ); IF has_sortorder THEN EXECUTE ' INSERT INTO pg_enum(enumtypid, enumlabel, enumsortorder) VALUES( '||eoid||', '||quote_literal(enum_elem)||', (SELECT MAX(enumsortorder) + 1 FROM pg_enum WHERE enumtypid='||eoid||') ) '; ELSE EXECUTE E'INSERT INTO pg_enum(enumtypid, enumlabel) VALUES('||eoid||', '||quote_literal(enum_elem)||')'; END IF; END; $body$ LANGUAGE 'plpgsql'; COMMENT ON FUNCTION enum.enum_add (enum_name character varying, enum_elem character varying) IS 'Inserts a new ENUM element wthout re-creating the whole type.'; непосредственно в таблице. Набор функций базы данных, предназначенных для манипулирования типами перечислений, можно найти здесь: PostgreSQL 8.3+, 9.1+ ALTER ENUM эмуляция: добавление / удаление элементов, транзакции .

Функция, которая добавляет новое значение в существующее перечисление, выглядит следующим образом:

using (var cmd = connection.CreateCommand())
{
    cmd.CommandText = @"enum.enum_add";
    cmd.Parameters.AddWithValue("enum_name", "attributeName");
    cmd.Parameters.AddWithValue("enum_elem", "O'Reilly");
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.ExecuteNonQuery();
}

Теперь вы можете просто вызвать хранимую процедуру / функцию из своего кода на C #:

ALTER TYPE

Обратите внимание, что вышеуказанная функция не будет работать, если вы попытаетесь добавить существующее значение.


0

У меня нет опыта работы с npgsql, хотя это может быть совершенно неправильно, но NpgsqlCommand, похоже, выполняет подготовленный оператор . Если это так, вы не можете подготовить заявление ALTER:

заявление

Любой оператор SELECT, INSERT, UPDATE, DELETE или VALUES.


0

PostgreSQL везде не поддерживает замещающие параметры, и, если я не ошибаюсь, он специально не поддерживается в операторах DDL, таких как ALTER TYPE. Вероятно, вам нужно будет вставить значение, которое вы хотите в качестве литерала в своем отчете (обязательно учтите SQL-инъекцию).

C #, npgsql, 9,6-PostgreSQL,