在postgresql中使用变量作为fieldname

时间:2014-04-28 15:12:12

标签: function postgresql plpgsql dynamic-sql

我有一个函数,我希望能够在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

建议?

2 个答案:

答案 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赋值运算符为:=(但在我的回答中不需要)。

  • 尝试搜索 + 以获取更多示例:
    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;