我有一些PL/pgSQL代码如下:
DECLARE
v_schema_name pg_catalog.pg_namespace.nspname%type := 'my_schema';
v_table_name pg_catalog.pg_tables.tablename%type := 'my_table';
v_column_name pg_catalog.pg_attribute.attname%type := 'my_column';
v_new_type TEXT := 'DECIMAL(16, 12)';
BEGIN
-- Omitted other code using v_new_type
EXECUTE format(
'ALTER TABLE %I.%I ALTER COLUMN %I TYPE %I',
v_schema_name,
v_table_name,
v_column_name,
v_new_type
);
END;
这将导致以下错误:
错误:类型“DECIMAL(16,12)”不存在
我尝试将格式字符串的最后一部分改为%L
,但导致以下错误:
错误:语法错误位于或接近“'DECIMAL(16,12)'”
我如何参数化这个查询?我需要把它分成三个部分吗?
更新:
- "The types decimal and numeric are equivalent."
numeric
类型可以在select * from pg_catalog.pg_type where typname = 'numeric';
中找到,因此v_new_type pg_catalog.pg_type.typname%type := 'decimal';
应该是可用的。
2条答案
按热度按时间3gtaxfhh1#
Postgres中的类型规范可能会非常复杂,因为ANSI SQL类型像
DOUBLE PRECISION
或TIMESTAMP WITH TIME ZONE
。Postgres的解析器应该支持这些类型的解析,然后这种语法只允许用于内置类型。对于更常见的类型,类型规范有两个部分:标识符和可选的类型修饰符。所以你的代码应该看起来像:注意-你可以像使用proposes @klin一样使用%s,并且你可以通过转换为regtype来清理它。但是它需要正确输入类型名称。
yzckvree2#
类型声明既不是标识符也不是文字。使用
%s
。