【问题标题】:Postgres accessing row values in a FOR loopPostgres 在 FOR 循环中访问行值
【发布时间】:2019-01-13 22:06:31
【问题描述】:

我是 Postgres 的新手。这是我的job_defn的结构和一些示例数据:

CREATE TABLE job_defn (
        job_id INTEGER NOT NULL,
        job_name CHARACTER VARYING(255) NOT NULL,
        system CHARACTER VARYING(50) NOT NULL,
        frequency CHARACTER VARYING(10) NOT NULL,
        run_day_id INTEGER NOT NULL,
        run_day_of_month INTEGER NOT NULL,
        eff_start_date DATE NOT NULL,
        eff_end_date DATE NOT NULL
    );

样本数据:

---------------------------
job_id         frequency
---------------------------
1001           DAILY 
1002           WEEKLY
---------------------------

在运行以下函数时,我期望l_freq 变量包含表中的frequency 列值。但是,即使表行包含一个值,它也总是打印 NULL:

CREATE OR REPLACE FUNCTION testing()
   RETURNS void AS $$
   DECLARE

       l_job_id INTEGER;
       l_job_defn_record job_defn%ROWTYPE;
       l_freq CHARACTER VARYING(10);
   BEGIN
       FOR l_job_defn_record IN 
               SELECT job_id, frequency FROM job_defn ORDER BY job_id ASC
       LOOP
               l_job_id := l_job_defn_record.job_id;
               l_freq := l_job_defn_record.frequency;
               raise info'job id: %,  frq: %', l_job_id, l_freq;
               raise info'row==>%', l_job_defn_record;

       END LOOP;
   END;
   $$ LANGUAGE plpgsql VOLATILE;

日志:

17:50:52  [CREATE - 0 row(s), 0.036 secs]  Command processed. No rows were affected
Code: 0 SQL State: 00000 --- job id: 10001,  frq: <NULL>
Code: 0 SQL State: 00000 --- row==>(10001,DAILY,,,,,,,,,,)
Code: 0 SQL State: 00000 --- job id: 10001,  frq: <NULL>
Code: 0 SQL State: 00000 --- row==>(10001,DAILY,,,,,,,,,,)
Code: 0 SQL State: 00000 --- job id: 10001,  frq: <NULL>
Code: 0 SQL State: 00000 --- row==>(10001,DAILY,,,,,,,,,,)
Code: 0 SQL State: 00000 --- job id: 10001,  frq: <NULL>
Code: 0 SQL State: 00000 --- row==>(10001,DAILY,,,,,,,,,,)
Code: 0 SQL State: 00000 --- job id: 10001,  frq: <NULL>
Code: 0 SQL State: 00000 --- row==>(10001,DAILY,,,,,,,,,,)
Code: 0 SQL State: 00000 --- job id: 10001,  frq: <NULL>
Code: 0 SQL State: 00000 --- row==>(10001,DAILY,,,,,,,,,,)
Code: 0 SQL State: 00000 --- job id: 10001,  frq: <NULL>
Code: 0 SQL State: 00000 --- row==>(10001,DAILY,,,,,,,,,,)
Code: 0 SQL State: 00000 --- job id: 10002,  frq: <NULL>
Code: 0 SQL State: 00000 --- row==>(10002,WEEKLY,,,,,,,,,,)
... 1 statement(s) executed, 0 row(s) affected, exec/fetch time: 0.036/0.000 sec  [0 successful, 1 warnings, 0 errors]

【问题讨论】:

  • 功能好像没问题,问题可能出在列的类型上。编辑问题并添加表定义(psql 中的\d job_defn
  • 您好 klin,我已添加表定义。请提出建议。

标签: postgresql loops rows variable-assignment plpgsql


【解决方案1】:

您将记录变量l_job_defn_record 声明为类型job_defn%ROWTYPE。正如您后来澄清的那样,job_defn 表实际上不仅仅包含您第一次披露的两列。 FOR 循环中的赋值只赋值记录变量的前两个字段

...
   FOR l_job_defn_record IN 
      SELECT job_id, frequency FROM ...  -- wrong!
...

这样,SELECT 查询 (job_defn.frequency) 的第二列被分配给记录变量 (l_job_defn_record.job_name) 的第二个字段 - 显然不是预期的那样。它恰好可以工作,因为frequency 也是varchar 类型。记录的尾随字段未分配,默认为NULL

这会解决它:

...
   FOR l_job_defn_record IN 
      SELECT * FROM job_defn ORDER BY job_id
...

通常,SELECT * 是可疑编码,但在这种情况下,这是正确的方法,因为根据定义,l_job_defn_record 与表 job_defn 具有相同的行类型。

【讨论】:

  • 非常感谢您的解释,建议更改修复它:)
【解决方案2】:

Erwin 在他的回答中清楚地解释了错误的原因。我建议使用the RECORD type 作为变量,而不是ROWTYPE

    l_job_defn_record RECORD;

这种变量的实际结构是在为其赋值时动态定义的。因此不存在变量与赋值不兼容的可能性。

【讨论】:

  • 非常感谢,建议更改修复它:)
猜你喜欢
  • 1970-01-01
  • 2013-10-09
  • 2016-10-29
  • 1970-01-01
  • 2020-10-11
  • 2013-07-10
  • 1970-01-01
  • 2016-02-12
  • 1970-01-01
相关资源
最近更新 更多