热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

探索Oracle自动类型转换(下)

点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!!
点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!!

自动类型转换常见错误

下面选择一个在PL/SQL程序中的常犯错误说明自动类型转换容易导致的问题,特别是DATE类型自动转换导致问题,希望给予读者一些警示,不要使用自动类型转换,上篇文章已经说了这么多缺点,这里就不重复叙述了。
请看例子,为了简单说明只建了表未插入数据,有兴趣的可以自己插入数据测试一下:

DINGJUN123>DROP TABLE t;

表已删除。

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 14
ORA-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);

上面的chr(39)就是单引号,因为在字符串中表示一个单引号比较麻烦,所以用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'

PL/SQL 过程已成功完成。

DINGJUN123>
PRINT o_count

O_COUNT
----------
0

首先SYSDATE转为字符串,将SQL拼凑好,结果就是上面打印出的语句,然后执行SQL,右边的'2021-06-12'遇到了左值是DATE类型,又进过一次类型转换,将字符串转为DATE类型,转换的过程很复杂。这种拼凑SQL的方式也是不可取的
自动类型转换特别是在日期类型的处理过程中,经常发生类似的错误,如果有很好的编码习惯,这种错误是完全可以避免的,类似这样的查询,不应该使用常量直接拼凑,一般应使用绑定变量的方式:

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> : i_date ';
12 DBMS_OUTPUT.PUT_LINE(v_sql);
13 EXECUTE IMMEDIATE v_sql INTO o_count
14 USING i_date;
15 END;
16 /

过程已创建。

DINGJUN123>EXEC sp_t ('t',sysdate,:o_count);
SELECT COUNT(*) FROM t WHERE done_date> : i_date

PL/SQL 过程已成功完成。

DINGJUN123>PRINT o_count
O_COUNT
----------

0


本文作者:丁 俊(上海新炬王翦团队)

本文来源:“IT那活儿”公众号


推荐阅读
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 包含phppdoerrorcode的词条 ... [详细]
  • 一个建表一个执行crud操作建表代码importandroid.content.Context;importandroid.database.sqlite.SQLiteDat ... [详细]
  • MySQL初级篇——字符串、日期时间、流程控制函数的相关应用
    文章目录:1.字符串函数2.日期时间函数2.1获取日期时间2.2日期与时间戳的转换2.3获取年月日、时分秒、星期数、天数等函数2.4时间和秒钟的转换2. ... [详细]
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • 本文总结了在SQL Server数据库中编写和优化存储过程的经验和技巧,旨在帮助数据库开发人员提升存储过程的性能和可维护性。 ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • 本文介绍了如何使用Flume从Linux文件系统收集日志并存储到HDFS,然后通过MapReduce清洗数据,使用Hive进行数据分析,并最终通过Sqoop将结果导出到MySQL数据库。 ... [详细]
  • Linux CentOS 7 安装PostgreSQL 9.5.17 (源码编译)
    近日需要将PostgreSQL数据库从Windows中迁移到Linux中,LinuxCentOS7安装PostgreSQL9.5.17安装过程特此记录。安装环境&#x ... [详细]
  • 本文介绍了在 MySQL 中如何使用正则表达式来提高查询效率,通过具体示例展示了如何筛选包含中文字符的记录,并详细解释了正则表达式的各种特殊字符和结构。 ... [详细]
  • oracle c3p0 dword 60,web_day10 dbcp c3p0 dbutils
    createdatabasemydbcharactersetutf8;alertdatabasemydbcharactersetutf8;1.自定义连接池为了不去经常创建连接和释放 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 在使用达梦数据库时,管理员可能会遇到连接频繁中断或特定SQL语句语法错误的问题。这些问题通常源于开发人员在创建对象时的不规范操作。为了解决这些问题,建议对数据库配置进行优化,并确保所有SQL语句符合达梦数据库的标准语法。此外,定期检查和维护数据库连接参数,以及对异常日志进行详细分析,也有助于及时发现并解决问题。 ... [详细]
author-avatar
茶茶
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有