7、日期和字符型必须要使用引号来处理

  下面的示例中,使用了日期型变量,未使用引号标注,且使用了变量绑定,但直接输入日期型数据,而不加引号,则收到错误提示。

DECLARE
         sql_stat  VARCHAR2(100);
         v_date    DATE :=&dt;      --定义日期型变量,未使用引号
         v_empno   NUMBER :=7900;
         v_ename   tb_emp.ename%TYPE;
         v_sal     tb_emp.sal%TYPE;
        
       BEGIN
         sql_stat := 'SELECT ename,sal FROM tb_emp WHERE hiredate=:v_date';    --使用了占位符:v_date进行变量绑定
                 
         EXECUTE IMMEDIATE sql_stat
         INTO v_ename,v_sal
         USING v_date;
         DBMS_OUTPUT.PUT_LINE('Employee Name '||v_ename||', sal is '||v_sal);
       END;
 
       Enter value for dt: 1981-05-01              --执行时,输入的字串中也未使用引号,此时收到错误提示
       old   3:   v_date    DATE :=&dt;
       new   3:   v_date    DATE :=1981-05-01;
         v_date    DATE :=1981-05-01;
                        *
       ERROR at line 3:
       ORA-06550: line 3, column 20:
       PLS-00382: expression is of wrong type
       ORA-06550: line 3, column 13:
       PL/SQL: Item ignored
       ORA-06550: line 13, column 9:
       PLS-00320: the declaration of the type of this expression is incomplete or malformed
       ORA-06550: line 11, column 3:
       PL/SQL: Statement ignored

  处理办法一

  执行时输入带引号的字串

flasher@ORCL> /
Enter value for dt: '1981-05-01'
old   3:   v_date    DATE :=&dt;
new   3:   v_date    DATE :='1981-05-01';
Employee Name BLAKE, sal is 2850

PL/SQL procedure successfully completed.

  处理办法二

  在声明变量时赋值用引号,如下

v_date    DATE :='&dt';

  如存在字符格式转换,可以直接使用转换函数,如

v_date    DATE :=TO_DATE('&dt','DD-MON-RR');

  如果上面的例子中,动态SQL语句不使用绑定日期变量,而是将其连接成字符串,则可以使用下面的方式来实现

DECLARE
         sql_stat  VARCHAR2(100);
         v_date    DATE :='&dt';
         v_empno   NUMBER :=7900;
         v_ename   tb_emp.ename%TYPE;
         v_sal     tb_emp.sal%TYPE;
        
       BEGIN
         sql_stat := 'SELECT ename,sal FROM tb_emp WHERE hiredate=' || chr(39) ||v_date|| chr(39);--chr(39)代表单引号
         EXECUTE IMMEDIATE sql_stat
         INTO v_ename,v_sal;
         DBMS_OUTPUT.PUT_LINE('Employee Name '||v_ename||', sal is '||v_sal);
       END;
 
       Enter value for dt: 1981-05-01
       old   3:   v_date    DATE :='&dt';
       new   3:   v_date    DATE :='1981-05-01';
       SELECT ename,sal FROM tb_emp WHERE hiredate='1981-05-01'
       Employee Name BLAKE, sal is 2850
 
       PL/SQL procedure successfully completed.