【问题标题】:00984. 00000 - "column not allowed here"00984. 00000 - “此处不允许列”
【发布时间】:2015-01-30 11:46:39
【问题描述】:

我正在尝试创建以下 PL/sql 但出现错误

创建新的匿名 PL/SQL 块:

  • 首先,从employees表中选择雇员总数、平均工资、最高工资和最低工资到PL/SQL变量中。平均工资应四舍五入为整数

  • 然后创建一个包含以下列的表 stats:

    the_date   DATE,                                        
    emp_num NUMBER                              
    avg_sal   NUMBER                                    
    max_sal   NUMBER                                
    min_sal   NUMBER          
    
  • 然后使用上述 PL/SQL 变量将今天日期、员工总数、平均工资、最高工资和最低工资的值插入到统计表中

  • 最后打印在屏幕上。

我的代码:

DECLARE
 v_emp_no Number;
 v_av_sal Number;
 v_mx_sal Number;
 v_mn_sal Number;
BEGIN
 SELECT count(employee_id) as total_emp, ROUND(AVG(salary))as avg_sal, MAX(salary)as max_sal, MIN(salary)as min_sal
 INTO v_emp_no, v_av_sal, v_mx_sal, v_mn_sal
 FROM employees;
 EXECUTE IMMEDIATE 'CREATE TABLE stats (the_date DATE, emp_num NUMBER, avg_sal NUMBER, max_sal NUMBER, min_sal NUMBER)';
 EXECUTE IMMEDIATE 'INSERT INTO stats values (sysdate, v_emp_no, v_av_sal, v_mx_sal, v_mn_sal)';
 EXECUTE IMMEDIATE 'DROP TABLE stats';
 DBMS_OUTPUT.PUT_LINE('Today our company has '||v_emp_no||' emplyees');
 DBMS_OUTPUT.PUT_LINE('The average salary in the company is '||v_av_sal);
 DBMS_OUTPUT.PUT_LINE('The maximum salary in the company is '||v_mx_sal);
 DBMS_OUTPUT.PUT_LINE('The minimum salary in the company is '||v_mn_sal);
END;
/

但出现以下错误

Error report -
ORA-00984: column not allowed here
ORA-06512: at line 11
00984. 00000 -  "column not allowed here"
*Cause:    
*Action:

【问题讨论】:

  • 为什么 PL/SQL 可以在普通 SQL 中完成。

标签: oracle plsql dynamic-sql


【解决方案1】:

在这一行:

EXECUTE IMMEDIATE 'INSERT INTO stats values (sysdate, v_emp_no, v_av_sal, v_mx_sal, v_mn_sal)';

变量名没有引用您的变量,而是被视为列名。

您需要为此使用绑定变量:

EXECUTE IMMEDIATE 'INSERT INTO stats values (sysdate, :1, :2, :3, :4)'
  USING v_emp_no, v_av_sal, v_mx_sal, v_mn_sal;

【讨论】:

    【解决方案2】:

    EXECUTE IMMEDIATE 'INSERT INTO stats values (sysdate, v_emp_no, v_av_sal, v_mx_sal, v_mn_sal)';

    这是错误的。因为,v_emp_no, v_av_sal, v_mx_sal, v_mn_sal变量,而不是。您需要将它们视为变量。

    编辑

    您不应该(ab)将动态 SQL 用于此类琐碎的任务。

    退一步想一想,难道不应该用普通的SQL而不是PL/SQL来完成吗?整个匿名块不过是三个 SQL 语句 -

    SQL> CREATE TABLE stats
      2    (
      3      the_date DATE,
      4      emp_num  NUMBER,
      5      avg_sal  NUMBER,
      6      max_sal  NUMBER,
      7      min_sal  NUMBER
      8    );
    
    Table created.
    
    SQL> INSERT INTO stats
      2  SELECT sysdate,
      3    COUNT(empno)    AS total_emp,
      4    ROUND(AVG(sal)) AS avg_sal,
      5    MAX(sal)        AS max_sal,
      6    MIN(sal)        AS min_sal
      7  FROM emp;
    
    1 row created.
    
    SQL> SELECT * FROM stats;
    
    THE_DATE     EMP_NUM    AVG_SAL    MAX_SAL    MIN_SAL
    --------- ---------- ---------- ---------- ----------
    30-JAN-15         14       2073       5000        800
    
    SQL>
    SQL> DROP TABLE stats PURGE;
    
    Table dropped.
    

    【讨论】:

    • 绑定变量而不是串联,确定吗?
    • 是的,好点。我宁愿不使用 PL/SQL,而是用普通的 SQL 来做。编辑了我的答案。
    • 我认为这是一个练习;否则为什么还要打扰这张桌子,为什么不单独使用普通的select?无论哪种方式创建和删除表似乎......过度。
    • 嗯,同意。然而,像 stats 这样的表格并不总是应该只是一个选择。在分析领域,为了创建 BI 仪表板,像统计数据这样的表格是有意义的。
    • 当然,但不要创建它并立即删除它。虽然 *8-) 但谁知道 OP 的想法是什么
    猜你喜欢
    • 2020-03-31
    • 2015-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多