博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
项目开发之存储过程发生的那些事
阅读量:5925 次
发布时间:2019-06-19

本文共 2151 字,大约阅读时间需要 7 分钟。

hot3.png

前言   

       之前在项目开发过程中,需要有一步操作就是使用存储过程删除一系列相关的表,再使用mybatis调用该存储过程,输入参数为家人账号,类型为String,数据库表结构中,该账号字段类型为varchar2,再实操的过程中,没有发生错误,可能是输入参数虽然传入的是String类型,但是该账号内容全部为数字,因为在执行过程中就报“ORA-01722: 无效数字”异常了。         

原因分析

         输入参数虽然是字符串类型,但是内容均为数字,在执行存储过程字符串拼接时,如果是使用“||”符号进行拼接,那么拼接后的sql是没有单引号的,也就是比如存储过程中某条语句:execu_sql := 'delete from userinfo where account = ' ||account;(execu_sql为在存储过程定义的变量,为varchar(2000),":="为赋值操作,相当于把这条sql赋值给execu_sql这个表变量进行保存),但是执行完成后,execu_sql这个变量内容为:"delete from userinfo where account = XXXXXX",我们知道,把这个sql运行,肯定会报无效数字异常的,因此异常就是这样出现的,因为oracle有隐式转换机制,如果你传入的虽然是String类型的变量,但是如果变量的内容全部都会数字,那么oracle默认会将该String类型变量转化为数字,那么运行时就会报错了。

解决方案

        那么我们在实操的过程中就要动态的拼接单引号了,可以使用ASCII 编码,单引号的ASCII 编码我39,那么存储过程sql可以这样写:execu_sql := 'delete from userinfo where account = '||chr(39)||account||chr(39);这样就不会出错了。

 

loop循环使用

       loop循环中可以循环调用存储过程而不会报错,例如:

     --循环创建明日的表

     loop
   --抽取方法,检查今天的表有无创建,如果没有就创建
   create_gps_day_table(current_datetime);
   
   --抽取方法,检查今天表序列是否创建,如果没有就创建
   create_gps_day_seq(current_datetime);
   
   current_datetime := current_datetime+1;
   --当中间天数小于结束月份天数跳出循环
    exit when current_datetime>end_datetime;
    end loop; 

    但是如果loop循环中循环执行多条sql操作,则循环会失效,例如:

     loop    

       execu_sql := 'alter table '||table_names||' add(datas clob)';
       execute immediate execu_sql;
      
       execu_sql := 'update '||table_names||' set datas = data';
       execute immediate execu_sql;
   
       execu_sql := 'alter table '||table_names||' drop column data'; 
       execute immediate execu_sql;
   
       execu_sql := 'alter table '||table_names||' rename column datas to data';
       execute immediate execu_sql;
   
       start_datetime := start_datetime+1;
   
       exit when start_datetime>current_datetime;
     end loop;  

     或者一条存储过程中写多个循环,并且循环中执行一条sql操作,则第一条循环能成功,而后续循环均报:

ORA-00942:表或视图不存在错误。例如:

     loop    

       table_names := 'tb_app_time_'||start_datetime;
 
       execu_sql := 'alter table '||table_names||' add(datas clob)';
       execute immediate execu_sql;
   
       start_datetime := start_datetime + 1;
   
       exit when start_datetime>end_datetime;
     end loop;  
 
      loop          
       table_names := 'tb_app_time_'||start_datetime;
   
       execu_sql := 'update '||table_names||' set datas = data';
       execute immediate execu_sql;
   
       start_datetime := start_datetime+1;
   
       exit when start_datetime>end_datetime;
     end loop; 

转载于:https://my.oschina.net/u/3872757/blog/2051725

你可能感兴趣的文章
mysql对于imoji表情的支持
查看>>
基于ZooKeeper的分布式Session实现
查看>>
演讲实录|马晓宇:When TiDB Meets Spark
查看>>
java web 文件上传下载
查看>>
详有记录
查看>>
代码设计模式之简单工厂模式(Factory)
查看>>
JSP打入jar包
查看>>
NSThread
查看>>
Linux下安装Maven3.1.1
查看>>
面试题(9)
查看>>
MySQL数据库优化那些事
查看>>
CSS样式的优先级对比验证
查看>>
php中mysql和mysqli的区别
查看>>
在Mac上配置Sublime Text 2
查看>>
《开源安全运维平台OSSIM最佳实践》当当自营店 3-15活动 ,仅售 6 折
查看>>
从0到1使用Kubernetes系列(五):Kubernetes Scheduling
查看>>
Choerodon 的微服务之路(四):深入理解微服务配置中心
查看>>
JS格式化数字金额用逗号隔开保留两位小数
查看>>
国内的maven repository镜像
查看>>
Spring Cloud Alibaba基础教程:Nacos配置的加载规则详解
查看>>