基于功能查看,正确查询视为坏

时间:2016-06-28 07:38:03

标签: oracle plsql

这是代码:

CREATE TABLE emp_where (where_clause VARCHAR2(4000));
INSERT INTO emp_where (where_clause)
VALUES ('first_name=''KING'' or department_id = 20');
commit;

CREATE OR REPLACE TYPE t_emp_rec AS OBJECT (
          EMPLOYEE_ID    NUMBER(4),
          FIRST_NAME    VARCHAR2(10),
          JOB_ID      VARCHAR2(9),
          MANAGER_ID      NUMBER(4),
          HIRE_DATE DATE,
          SALARY     NUMBER(7,2),
          DEPARTMENT_ID   NUMBER(2)
);
/
CREATE OR REPLACE TYPE t_emp_tab AS TABLE OF t_emp_rec;
 /

 CREATE OR REPLACE FUNCTION emp_fn RETURN t_emp_tab
 PIPELINED IS
   l_sql   VARCHAR2(32767);
   l_where VARCHAR2(4000);
   TYPE l_cur_type IS REF CURSOR;
   l_cur l_cur_type;
   l_rec employees%ROWTYPE;
 BEGIN
   SELECT where_clause INTO l_where FROM emp_where;
   l_sql := 'SELECT * FROM employees WHERE ' || l_where;
   OPEN l_cur FOR l_sql;
   LOOP
     FETCH l_cur
     INTO l_rec;
     EXIT WHEN l_cur%NOTFOUND;
     PIPE ROW(t_emp_rec(EMPLOYEE_ID    => l_rec.EMPLOYEE_ID
                       ,FIRST_NAME    => l_rec.FIRST_NAME
                       ,JOB_ID      => l_rec.JOB_ID
                       ,MANAGER_ID      => l_rec.MANAGER_ID
                       ,hire_date => l_rec.hire_date
                       ,SALARY      => l_rec.SALARY
                       ,DEPARTMENT_ID   => l_rec.DEPARTMENT_ID));
 END LOOP;

 RETURN;
EXCEPTION
 WHEN OTHERS THEN
   raise_application_error(-20000, SQLERRM || chr(10) || l_sql);
 END;
 /

 CREATE OR REPLACE VIEW emp_vw AS


UPDATE emp_where SET where_clause = 'EMPLOYEE_ID BETWEEN 100 and 200';
COMMIT;
SELECT * FROM emp_vw;

当我使用此子句执行SELECT * FROM emp_vw;时:EMPLOYEE_ID BETWEEN 100 and 200 Oracle给了我一个错误

ORA-20000:ORA-06502:PL / SQL:数字或值错误:数字精度太大 SELECT * FROM employees WHERE EMPLOYEE_ID在100和200之间

但是当我执行查询本身(SELECT * FROM employees WHERE EMPLOYEE_ID BETWEEN 100和200)时,没有错误。另一种情况 - 当子句是' deparment_id = 20'时,执行视图是正确的。但是当我改变' ='到'>' (department_id> 20) - numeric or value error: number precision too large。 有人可以解释一下这是怎么回事吗?

1 个答案:

答案 0 :(得分:1)

如果我跑:

DESCRIBE employees

然后我得到输出:

Name           Null     Type         
-------------- -------- ------------ 
EMPLOYEE_ID    NOT NULL NUMBER(6)    
FIRST_NAME              VARCHAR2(20) 
LAST_NAME      NOT NULL VARCHAR2(25) 
EMAIL          NOT NULL VARCHAR2(25) 
PHONE_NUMBER            VARCHAR2(20) 
HIRE_DATE      NOT NULL DATE         
JOB_ID         NOT NULL VARCHAR2(10) 
SALARY                  NUMBER(8,2)  
COMMISSION_PCT          NUMBER(2,2)  
MANAGER_ID              NUMBER(6)    
DEPARTMENT_ID           NUMBER(4)    

如果将它与t_emp_rec对象进行比较,那么您将看到大多数对象属性的大小都比表格列小。

将对象更改为具有相同的大小,它应该起作用:

CREATE OR REPLACE TYPE t_emp_rec AS OBJECT (
  EMPLOYEE_ID     NUMBER(6),
  FIRST_NAME      VARCHAR2(20),
  JOB_ID          VARCHAR2(10),
  MANAGER_ID      NUMBER(6),
  HIRE_DATE       DATE,
  SALARY          NUMBER(8,2),
  DEPARTMENT_ID   NUMBER(4)
);
/