我有一个函数,我希望能够在Postgres函数中使用文本变量作为字段名称。
DECLARE
_currentEmployee text;
_myCount integer;
BEGIN
FOR _record IN
SELECT ...
LOOP
_currentEmployee = _record.name
_myCount = (SELECT count(*) FROM tblTraining
WHERE tblTraining._currentEmployee = 4);
If _mycount = 0 ...
END LOOP;
基本上,检查每位员工的培训记录是例行公事。表模式有明显的问题,因为员工都在训练表中作为列输入,而不是每行中的标准化id,但我必须使用我在这里得到的内容。
每当我运行该函数时,它会逐字地处理_currentEmployee
,而不是用字段名称替换它并正确处理。我收到错误:
_currentlEmployee is not a field of tblTraining
建议?
答案 0 :(得分:4)
通常,SQL中不允许使用参数化标识符。
在PL / pgSQL函数中,这可以通过EXECUTE
执行的动态SQL字符串来规避。警惕SQL注入。列名必须像用户输入一样对待。
DECLARE
_rec record;
_ct integer;
BEGIN
FOR _rec IN
SELECT ...
LOOP
EXECUTE format(
'SELECT count(*) FROM tblTraining
WHERE tbltraining.%I = 4', _rec.name); -- %I avoids SQL injection
INTO _ct;
IF _ct = 0 THEN ...
END LOOP;
format()
%I
将字符串清理为有效标识符。防止语法错误和SQL注入。请注意,Postgres中的不带引号的标识符始终是小写的。如果您的真实列名称较低,则必须在此处提供较低版本的版本
永远不要在Postgres中使用CaMeL案例标识符来避免所有相关问题开始。
plpgsql赋值运算符为:=
(但在我的回答中不需要)。
尝试搜索plgsql + dynamic-sql以获取更多示例:
https://stackoverflow.com/questions/tagged/plpgsql+dynamic-sql
答案 1 :(得分:1)
EXECUTE应该是你这个任务的朋友。
http://www.postgresql.org/docs/9.3/static/plpgsql-statements.html
EXECUTE 'SELECT count(*) FROM tblTraining WHERE '
|| _currentEmployee
|| ' = 4'
INTO _myCount;