首页 > 解决方案 > 为什么 pl sql 赋值运算符在读取 sql 查询时会抛出错误?

问题描述

set serveroutput on;
 declare

      v_emp_first_name  US_EMPLOYEES.FIRST_NAME%TYPE;

      BEGIN

       select us_employees.first_name into v_emp_first_name  from us_employees where email = 'jbutt@gmail.com';

       dbms_output.put_line('v_emp_first_name  --> ' || v_emp_first_name);

       v_emp_first_name := select first_name from us_employees where email = 'kris@gmail.com';

       dbms_output.put_line('v_emp_first_name  --> ' || v_emp_first_name);

      END;

当我编译上面的代码时,下面的语句会抛出错误

    v_emp_first_name := select first_name from us_employees where email = 'kris@gmail.com';

是否无法通过 sql 查询读取列值并使用赋值运算符映射该值?

如果我只有下面的代码,那么它可以编译并且工作正常

    select us_employees.first_name into v_emp_first_name  from us_employees where email = 'jbutt@gmail.com';

标签: oracleplsql

解决方案


最简洁的答案是不。您不能将标量查询的输出分配给变量。您的“作业”的正确语法是您已经知道的语法。

我相信你会问为什么。为什么 Oracle 选择那种“奇怪”的赋值语法,而不是你尝试过的更简单的语法?

答案是,在更一般的情况下,一条select语句可能返回多个列,而不仅仅是一个;并且来自多个列的值可以同时“分配”给多个变量(PL/SQL 块的本地变量)。顺便说一句,这是更常见的用法——人们一次提取一个“记录”,而不是一个值。那么,您将如何将“select into ”操作重写为“作业”(或多个“作业”)?没有自然的方法可以做到这一点。

您可能会问为什么 Oracle 不允许在选择单个列的情况下使用“您的”赋值语法,以及select into语法(无论如何,多列行都需要这种语法)。答案是那会很浪费。我们已经有了一个语法——无论如何我们都需要更一般的情况;我们不再需要一个。

您可能会说我们可以将所有接收局部变量放入一个记录类型中,并且即使对于由 a 返回的一般“行”,也可以(对记录)进行一次赋值select。唉,SQL 语句返回行,而不是记录;行是一个 SQL 概念,特别是它们不是数据类型。也许甲骨文可以沿着这些路线做进一步的开发(添加今天不存在的功能),但是为什么要麻烦 - 他们已经有一个完美的语法来满足你的需要,而且你已经知道那个语法是什么 - 不需要定义保存所有局部变量的记录类型,然后为来自 SQLselect语句的行定义“记录类型”,然后......


推荐阅读