我正在尝试创建一个函数,但我无法在以下代码中找到错误:
CREATE OR REPLACE FUNCTION qwat_od.fn_label_create_fields(table_name varchar, position boolean = true, rotation boolean = true) RETURNS void AS
$BODY$
BEGIN
/* Creates columns */
EXECUTE 'ALTER TABLE qwat_od.'||table_name||' ADD COLUMN label_1_visible smallint default 1; ';
IF position IS TRUE THEN
EXECUTE 'ALTER TABLE qwat_od.'||table_name||' ADD COLUMN label_1_x double precision default null;';
EXECUTE 'ALTER TABLE qwat_od.'||table_name||' ADD COLUMN label_1_y double precision default null;';
END IF;
IF rotation IS TRUE THEN
EXECUTE 'ALTER TABLE qwat_od.'||table_name||' ADD COLUMN label_1_rotation double precision default null;';
END IF;
EXECUTE 'ALTER TABLE qwat_od.'||table_name||' ADD COLUMN label_1_text varchar(120);';
EXECUTE 'ALTER TABLE qwat_od.'||table_name||' ADD COLUMN label_2_visible smallint default 1; ';
IF position IS TRUE THEN
EXECUTE 'ALTER TABLE qwat_od.'||table_name||' ADD COLUMN label_2_x double precision default null;';
EXECUTE 'ALTER TABLE qwat_od.'||table_name||' ADD COLUMN label_2_y double precision default null;';
END IF;
IF rotation IS TRUE THEN
EXECUTE 'ALTER TABLE qwat_od.'||table_name||' ADD COLUMN label_2_rotation double precision default null;';
END IF;
EXECUTE 'ALTER TABLE qwat_od.'||table_name||' ADD COLUMN label_2_text varchar(120);';
/* Creates constraints */
EXECUTE 'ALTER TABLE qwat_od.'||table_name||' ADD CONSTRAINT '||table_name||'_label_1_visible FOREIGN KEY (label_1_visible) REFERENCES qwat_vl.visible(vl_code_int) MATCH FULL; CREATE INDEX fki_'||table_name||'_label_1_visible ON qwat_od.'||table_name||'(label_1_visible);';
EXECUTE 'ALTER TABLE qwat_od.'||table_name||' ADD CONSTRAINT '||table_name||'_label_2_visible FOREIGN KEY (label_2_visible) REFERENCES qwat_vl.visible(vl_code_int) MATCH FULL; CREATE INDEX fki_'||table_name||'_label_2_visible ON qwat_od.'||table_name||'(label_2_visible);';
END;
$BODY$
LANGUAGE 'plpgsql';
我明白了:
ERROR: syntax error at or near "position"
LINE 4: ...wat_od.fn_label_create_fields(table_name varchar, position b...
我在论证声明中做错了吗?
答案 0 :(得分:2)
@pozs already provided an explanation您看到的错误。
但还有更多。最重要的是,您对SQL injection持开放态度。
CREATE OR REPLACE FUNCTION qwat_od.fn_label_create_fields(_tbl text, _position bool = true, _rotation bool = true)
RETURNS void AS
$func$
BEGIN
/* Creates columns */
EXECUTE format('ALTER TABLE qwat_od.%I ADD COLUMN label_1_visible smallint default 1', _tbl);
IF _position THEN
EXECUTE format('ALTER TABLE qwat_od.%I
ADD COLUMN label_1_x double precision default null
, ADD COLUMN label_1_y double precision default null', _tbl);
END IF;
IF _rotation THEN
EXECUTE format('ALTER TABLE qwat_od.%I ADD COLUMN label_1_rotation double precision default null' , _tbl);
END IF;
EXECUTE format('ALTER TABLE qwat_od.%I
ADD COLUMN label_1_text varchar(120)
, ADD COLUMN label_2_visible smallint default 1', _tbl);
IF _position THEN
EXECUTE format('ALTER TABLE qwat_od.%I
ADD COLUMN label_2_x double precision default null
, ADD COLUMN label_2_y double precision default null', _tbl);
END IF;
IF _rotation THEN
EXECUTE format('ALTER TABLE qwat_od.%I ADD COLUMN label_2_rotation double precision default null', _tbl);
END IF;
EXECUTE format('ALTER TABLE qwat_od.%I ADD COLUMN label_2_text varchar(120)', _tbl);
/* Creates constraints */
EXECUTE format('ALTER TABLE qwat_od.%$1I
ADD CONSTRAINT %$2I FOREIGN KEY (label_1_visible) REFERENCES qwat_vl.visible(vl_code_int)
, ADD CONSTRAINT %$3I FOREIGN KEY (label_2_visible) REFERENCES qwat_vl.visible(vl_code_int);
CREATE INDEX %$4I ON qwat_od.%$1I(label_1_visible);
CREATE INDEX %$5I ON qwat_od.%$1I(label_2_visible)'
, _tbl
, _tbl || '_label_1_visible'
, _tbl || '_label_2_visible'
, 'fki_' || _tbl || '_label_1_visible'
, 'fki_' || _tbl || '_label_2_visible');
END
$func$ LANGUAGE plpgsql;
请务必使用明确有效的参数名称(position
为reserved word是主要错误。)
我使用format()
修复了SQL注入问题(因为使用regclass
的简单解决方案未涵盖您的连接名称,如@pozs所评论的那样)。详细解释:
_tbl
必须是不合格的表格名称("tbl"
,而不是"schema.tbl"
)。
不要引用语言名称,它是一个标识符:LANGUAGE plpgsql
在单个ALTER TABLE
语句中添加多个列/ sonstraints会更便宜。
其他各种简化/优化。