Oracle 在脚本的Where子句中使用变量

Oracle 在脚本的Where子句中使用变量,oracle,plsql,Oracle,Plsql,我不确定行变量中字段的这种用法,该变量已加载到“for”循环中 declare r_pers_rec &appOwner..personsTbl%ROWTYPE; cursor getItems is SELECT Fld1, Fld2 FROM srcTbl; begin for Rec in getItems loop BEGIN SELECT * INTO

我不确定行变量中字段的这种用法,该变量已加载到“for”循环中

declare
    r_pers_rec   &appOwner..personsTbl%ROWTYPE;

    cursor getItems is
            SELECT Fld1, Fld2
            FROM srcTbl;
begin
    for Rec in getItems 
    loop
        BEGIN
            SELECT * INTO r_pers_rec
            FROM   &appOwner..personsTbl
            WHERE  personnel_id = Rec.Fld1;
        END;
    end loop;
end;

Rec.Fld1
可以这样使用吗?

您的问题的简单答案是“是的,您可以在
WHERE
子句中使用
Rec.Fld1
,如图所示”

长答案是“是的,但总的来说,只有从SQL*Plus或其他解释替换变量的客户端运行时,脚本才能正常运行(这里,
&appOwner
)与SQL*Plus的方式相同。您可能还应该有一个异常处理程序来处理
找不到的数据
,因为如果给定值SRCTBL.FLD1在PERSONSTBL上没有值,则第二个SELECT可能会引发该异常

也许最好的答案是“摆脱这个问题”。重写脚本,通过将第二个
SELECT
构建到光标中来消除它,如下所示:

BEGIN
  FOR aRec IN (SELECT s.FLD1, s.FLD2, p.*
                 FROM srcTbl s
                 INNER JOIN &appOwner..personsTbl p
                   ON p.PERSONNEL_ID = s.FLD1)
  LOOP
    NULL;  -- Do whatever you need to do with your data here.
  END LOOP;
END;
正如一位比我聪明的人曾经观察到的那样,“我知道我在写代码,不是在没有什么可添加的时候,而是在没有什么可带走的时候”

上面的操作与原始代码相同,只是第二次选择不能抛出
NO_DATA\u FOUND
异常-相反,如果在PERSONSTBL表中找不到SRCTBL.FLD1的值,则不会返回任何行

如果确实希望始终返回SRCTBL中的数据,无论在PERSONSTBL上是否找到匹配的数据,请将脚本更改为

BEGIN
  FOR aRec IN (SELECT s.FLD1, s.FLD2, p.*
                 FROM srcTbl s
                 LEFT OUTER JOIN &appOwner..personsTbl p
                   ON p.PERSONNEL_ID = s.FLD1)
  LOOP
    NULL;  -- Do whatever you need to do with your data here. Note that in
           -- this case the PERSONSTBL values in aRec will not be populated
           -- (all will be NULL) if there is no matching row on PERSONSTBL
           -- for a given value of SRCTBL.FLD1
  END LOOP;
END;

祝你好运。

是的,看起来不错。(你不需要内在的开始/结束,但这不是问题。)你到底不确定什么?你试过了吗?有问题吗?如果是的话,发生了什么,你犯了什么错误?或者这是一个假设性的问题(这会更快地测试你自己)?以下是逐字解释的:“SELECT*INTO r_pers_rec FROM&appOwner..personsTbl WHERE PERSONERS_id=”,但可以说“rec.Fld1”是一个变量。之所以使用begin和end,是因为在实际脚本中,该部分有一个Exception子句。我在将代码放在S.O上时去掉了这一点。运行之后,我尝试使用dbms_output.put_line(r_pers_rec.first_name');(等等)。然而,我得到的表达式的类型是错误的。是的,它被有效地视为绑定变量。不过,你最后的评论并不是关于这一点,这相当令人困惑。你的问题应该显示实际出错的代码,以及完整的错误消息/堆栈。我将在13分钟后出发。很难知道错误发生在哪里,因为TOAD的编辑窗口和Oracle的响应没有给出有用的行号。如果我单击“回答你的问题”按钮,是否会向其他提交答案的人关闭此线程?scrTbl中的行包含文件夹中.PDFs的文件名,等待处理。对于每个文件名,我需要使用persons表中的值(除其他外)向表中添加一条记录(不是本问题中提到的任何表)。最终,将对.PDF的内容进行处理和存储。srcTbl中存储的文件名标识要处理的文件,以及persons表中的记录(即文件名的前10个字符do)。在开发过程中的这一点上,我只是尝试验证该过程,直到将记录从persons表中取出为止。一旦成功,我将在脚本中加入接下来的步骤,并运行脚本查找bug和语法错误。一旦我让整个脚本正常运行,我将在真实数据和.PDF文件上释放它。