表已删除。 DINGJUN123>CREATE TABLE t 2 (id NUMBER, 3 done_date DATE 4 );
表已创建。
--建立过程的时候并没有报错,我加了打印语句,方便下面看错误原因:
DINGJUN123>CREATE OR REPLACE PROCEDURE 2 sp_t (i_tabname VARCHAR2,i_date DATE,o_count OUT NUMBER) 3 /*********************************************************************** 4 ||desc:根据传入的表名和日期查询大于此日期的记录数 5 ||此函数应用的表都有相同的统计日期列done_date 6 ************************************************************************/ 7 AS 8 v_sql VARCHAR2(1000); 9 BEGIN 10 v_sql := 'SELECT COUNT(*) FROM ' 11 || i_tabname || ' WHERE done_date> ' 12 || i_date; 13 DBMS_OUTPUT.PUT_LINE(v_sql); 14 EXECUTE IMMEDIATE v_sql INTO o_count; 15 END; 16 /
过程已创建。
DINGJUN123>VAR o_count NUMBER DINGJUN123>SET SERVEROUTPUT ON DINGJUN123>EXEC sp_t ('t',SYSDATE,:o_count); SELECT COUNT(*) FROM t WHERE done_date> 12-6月 -21 BEGIN sp_t ('t', SYSDATE,:o_count); END;
*
第 1 行出现错误:
ORA-00933: SQL 命令未正确结束ORA-06512: 在 "DINGJUN123.SP_T", line 14ORA-06512: 在 line 1看到错误了吧,日期类型发生了类型转换,根据NLS_DATE_FORMAT和NLS_DATE_LANGUAGE参数设置自动变为字符串了,而且这个字符串还不是Oracle中的表示的字符串,看到了没有,是12-6月 -21而不是'12-6月 -21',很多人经常拼凑字符串的时候少了引号,当然这里拼凑加上引号是可以的,那么就有多次自动类型转换,将v_sql改为:
v_sql := 'SELECT COUNT(*) FROM ' ||i_tabname ||' WHERE done_date> ' ||chr(39) ||i_date ||chr(39);
DINGJUN123>ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD'; 会话已更改。 DINGJUN123>EXEC sp_t ('t', SYSDATE,:o_count); SELECT COUNT(*) FROM t WHERE done_date> '2021-06-12'