oracle数据类型及其隐式转换
- 格式:docx
- 大小:27.03 KB
- 文档页数:6
oracle数据类型以下的大多数类型的描述都经本人验证,但不免有错误,请不吝赐教(oracle: 10.2.0.3.0 ,plsql: 7.1.5.1398 )注:以下两个函数有助于理解数据类型length() 当前列存储值的字符长度;vsize() 当前列存储值所占用字节数。
1.CHAR固定长度字符域, 最大长度可达2000 个字符或者字节。
默认指定为以字符形式进行存储,并且当位数不够时oracle 在其右边添加空格来补满。
例如:2.VARCHAR2可变长度字符域,最大长度可达4000 个字符。
例如:CREATE TABLE test(name varchar2(20))2.1.CHAR和VARCHAR2区别1.CHAR 的长度是固定的,而VARCHAR2 的长度是可以变化的,比如,存储字符串,对于CHAR (20),表示你存储的字符将占20 个字节(包括17 个空字符),而同样的VARCHAR2 (20)则只占用3 个字节的长度,20 只是最大值,当你存储的字符小于20 时,按实际长度存储。
2 .CHAR 的效率比VARCHAR2 的效率稍高。
3.目前VARCHAR 是VARCHAR2 的同义词。
工业标准的VARCHAR 类型可以存储空字符串,但是Oracle 不这样做,尽管它保留以后这样做的权利。
Oracle 自己开辟了一个数据类型VARCHAR2,这个类型不是一个标准的VARCHAR,它将在数据库中varchar 列可以存储空字符串的特性改为存储NULL 值。
假如你想有向后兼容的能力,Oracle 建议使用VARCHAR2 而不是VARCHAR。
何时该用CHAR,何时该用varchar2?CHAR 与VARCHAR2 是一对矛盾的统一体,两者是互补的关系. VARCHAR2 比CHAR 节省空间,在效率上比CHAR 会稍微差一些,即要想获得效率,就必须牺牲一定的空间,这也就是我们在数据库设计上常说的‘以空间换效率’ 。
db2与oracle差别1:并发机制Oracle的默认隔离级是快照(Snapshot),写入事务可不能堵塞读取事务,读取事务能够猎取当前已提交值。
DB2默认是游标稳固性(Cursor Stability),写入事务会堵塞读取事务。
2: 数据类型数据库的核心是数据,类型不匹配或者语义的不同都会阻碍应用是否能够同时在两种数据库中运行。
Oracle支持一些非SQL标准的数据类型,例如VARCHAR2,这些是不被D B2支持的;另外,Oracle中的日期、时刻格式和DB2中相应类型在语义上不完全一致;最后Oracle的PL/SQL储备过程所支持的一些标量数据类型在DB2中需要被映射才能被识别。
如右:3: 隐式类型转换Oracle使用弱类型转换,而DB2使用强类型转换。
隐式类型转换能完成一种类型向另外一种类型的自动转换,关于不匹配的类型,假如数据类型能被合明白得释,比较或者赋值时能够执行隐式类型转换;强类型转换规则,意味着字符串和数字类型之间不能直截了当进行比较,除非显式转换。
4:SQL方言DB2传统上坚持对SQL标准的支持,但Oracle实现了专门多方言。
例如:CONNEC T BY 递归语句、(+)连接操作符、DUAL表、ROWNUM伪列、ROWID伪列、MINUS 操作符、SELECT INTO FOR UPDATE语句、TRUNCATE TABLE等。
假如要在DB2数据库上运行使用了上述方言的应用,就需要进行代码级别的翻译,工作量较大。
5:PL/SQL语言就储备过程和函数开发而言,DB2使用SQL PL语言来开发,Oracle使用PL/SQL 语言来开发。
SQL PL和PL/SQL差异庞大,这也是从Oracle到DB2转型最大的工作量所在。
6:内置包为了方便应用程序开发的需要,Oracle数据库提供了专门多内置包:DBMS_OUTPUT、DBMS_SQL、DBMS_ALERT、DBMS_PIPE、DBMS_JOB、DBMS_LOB、DBMS_UTI LITY、UTL_FILE、UTL_MAIL和UTL_SMTP等。
29.必须重视的Oracle自动类型转换显示类型转换以date类型为例子。
Oracle中对不同类型的处理具有显式类型转换(Explicit)和自动类型转换(隐式类型转换Implicit)两种方式,对于显式类型转换,我们是可控的,但是对于自动类型转换,当然不建议使用,因为很难控制,有不少缺点,但是我们很难避免碰到自动类型转换,如果不了解自动类型转换的规则,那么往往会改变我们SQL的执行计划,从而可能导致效率降低或其它问题,所以,Oracle开发人员很有必要了解Oracle自动类型转换的相关规则,从而避免自动类型转换导致相关问题的产生。
本章首先会对Oracle自动类型转换的规则做阐述,然后结合相关实例分析自动类型转换可能造成的问题。
29.1 数据类型优先级Oracle使用数据类型的优先级来决定自动类型转换,Oracle类型如下优先:■ Datetime and interval 类型■ BINARY_DOUBLE■ BINARY_FLOAT■ NUMBER■字符类型■所有其它内置类型上面说的不够具体,我们看第二节具体的类型转换规则。
29.2 自动类型转换规则一般一个表达式不能包含多种数据类型,比如一个表达式5*10然后加上'james',但是Oracle会有自动类型转换和显式类型转换两种规则,我们看如下例子:DINGJUN123>select 5*10+'james' from dual;select 5*10+'james' from dual*第1 行出现错误:ORA-01722: 无效数字我们看到,报无效数字错误。
当然,这里Oracle使用了自动类型转换将'james'转为数字类型,但是这个转换是失败的,所以报错,所以自动类型转换的第1个规则就是必须自动类型转换能够成功,否则报错。
我们看下面的就转换成功了:DINGJUN123>select 5*10+'2' from dual;5*10+'2'----------52OK,看到了结果正确,这里的字符串'2'被自动转为数值类型的2(不明白为什么会这样转换,请往下看),所以结果为52.。
Oracle的转换函数类型分为①隐形②显性隐式转换(有缺陷如下例子)例子'22.2'+10------------------------------------------这里的字符是有限定的必须是连续的数字((可以是小数)。
(注意:不能出现¥$ 与千分符,)----------32.2显示转化(重点)Tochar()将时间或日期转化成为字符to_char函数对日期转化格式:TO_CHAR(sysdate,‘yyyy-mm-dd hh:mi:ss’)要求:①必须包含在单引号中而且大小写敏感。
②可以包含任意的有效的日期格式。
③参数之间用逗号隔开。
详细见日期与字符串重要的例子:select to_char(sysdate,'yyyy"年"mm"月"dd')--------------------------如果想在年月日中使用(非:空格- /)字符串做为分割要使用“间隔内容”双引号from dualto_char对数字的转化9 数0 零$ 美元符L 本地货币符.-----点小数点,---逗号千位符格式示例:TO_CHAR(salary, '$99,999.00')例子:①select employee_id,to_char(salary,'99,999.00$')from employees结果等同于select employee_id,to_char(salary,'$99,999.00')from employees②select employee_id,to_char(salary,'$ 99,999.00')------------美元符号后面加了空格错误了(因为数字模型没有空格)from employeesto_number()将字符转化成为numberselect to_number('$99.123','$999.000')----------------------------(注意前面是3为小数。
oracle中convert函数用法Oracle中的convert函数是用来将一个表达式的数据类型转换为另一个数据类型的函数。
该函数可以将字符类型(如VARCHAR2类型)、日期类型和数字类型转换为其他类型。
convert函数的语法如下:CONVERT(e某pr1, data_type [, format])其中,e某pr1表示要转换的表达式,data_type表示要转换的目标数据类型,format是可选的,表示将数据转换为目标类型的格式。
以下是convert函数的常用数据类型和用法。
1.字符类型VARCHAR2和CLOB是Oracle中常见的字符类型。
在使用convert函数时,可以将它们转换为其他字符类型或数字类型。
例如,将一个字符串变为大写字母:SELECT CONVERT('hello', 'CHAR(5)') AS UpperCase FROM DUAL;结果为:HELLO2.日期类型日期类型在Oracle中有三种:DATE、TIMESTAMP和INTERVAL。
使用convert函数时,可以将它们转换为其他日期类型或字符类型。
例如,将一个日期转换为格式化的字符类型:SELECT CONVERT(TO_DATE('2022-02-22', 'yyyy-mm-dd'),'VARCHAR2(20)', 'dd/mm/yyyy') FROM DUAL;结果为:22/02/20223.数字类型Oracle中的数字类型包括:NUMBER、BINARY_FLOAT和BINARY_DOUBLE。
转换时,可以将它们转换为其他数字类型或字符类型。
例如,将一个整数转换为字符类型:SELECTCONVERT(123,'VARCHAR2(5)')FROMDUAL;结果为:123需要注意的是,convert函数不会隐式转换数据类型,因此需要显式指定目标数据类型和格式。
oracle sql数据类型函数一、Oracle SQL数据类型简介Oracle SQL支持多种数据类型,包括数值类型、字符串类型、日期和时间类型、布尔类型等。
了解这些数据类型有助于更好地利用Oracle SQL进行数据处理。
1.数值类型:包括整数类型(如INTEGER、SMALLINT、TINYINT)、浮点数类型(如FLOAT、DOUBLE PRECISION、NUMERIC)、decimal和char 类型等。
2.字符串类型:包括VARCHAR2、CHAR、NCHAR等。
3.日期和时间类型:包括DATE、TIMESTAMP、TIMESTAMP WITH TIME ZONE、INTERVAL等。
4.布尔类型:BOOLEAN。
二、Oracle SQL常用函数概述Oracle SQL提供了丰富的函数,可以方便地进行数据处理和分析。
以下为一些常用函数类别:1.数据类型转换与处理函数:如CAST、CONVERT、TRUNC等。
2.字符串处理函数:如LENGTH、SUBSTR、INSTR、LIKE等。
3.数学与逻辑运算函数:如SUM、AVG、MIN、MAX、MOD、LOG、POWER等。
4.日期和时间函数:如SYSDATE、TO_DATE、DATE_ADD、DATE_SUB 等。
5.聚合与分组函数:如GROUP BY、HAVING、SELECT DISTINCT等。
三、实战案例与应用以下为一个简单的实战案例,演示如何使用Oracle SQL数据类型和函数进行数据处理:假设我们有一个员工表(EMPLOYEE),包含以下字段:ID(整数类型)、NAME(字符串类型)、AGE(整数类型)、DEPARTMENT(字符串类型)、SALARY(浮点数类型)、HIRE_DATE(日期类型)、LEAVE_DATE(日期类型)。
1.查询所有员工的详细信息:```SELECT * FROM EMPLOYEE;```2.查询年龄大于30岁的员工名单:```SELECT NAME FROM EMPLOYEE WHERE AGE > 30;```3.计算所有员工的薪资总额:```SELECT SUM(SALARY) FROM EMPLOYEE;```4.查询各部门的平均年龄:```SELECT DEPARTMENT, AVG(AGE) FROM EMPLOYEE GROUP BY DEPARTMENT;```5.统计员工离职人数:```SELECT COUNT(*) FROM EMPLOYEE WHERE LEAVE_DATE IS NOT NULL;```通过以上案例,我们可以看到Oracle SQL数据类型和函数在实际应用中的重要作用。
数据类型-转换-隐式转换和显式转换数据类型转换分为隐式转换和显式转换,根据不同的转换对象,来确定是那种类型的转换。
隐式转换:就是系统默认的、不需要加以声明就可以进⾏转换。
⾸先来说在程序语⾔中默认的类型,⼀般整数是int类型,浮点数(3.14),默认就是double类型。
但是还有其他类型的,例如整数类型的long,浮点数的float。
当相同类型之间相遇的时候,就会出现隐式转换的问题。
那么隐式转换的规则就是根据数据类型从⼩到⼤的转换:byte→short→int→long(整数类型)例如:long num1 = 100;这个num1根据类型命名为long整数型,但是右侧的100在程序语⾔中默认为是int整数类型。
然⽽根据隐式转换规则,int类型可以⾃动的转换为long整数类型。
故⽽在程序运⾏的时候不会出现错误。
float→double(浮点数)例如:double num1 = 2.5F(F在这⾥代表是float类型的意思);这个同上复述。
num1是double类型,但是2.5F是float类型,因为符合隐式转换的规则,所以2.5F会⾃动的转换为双精度类型,2.50.显⽰转换:当系统默认转换不能转换的时候,⽽我们⼜需要把某⼀类型改为另⼀个类型,这个过程我们称之为显⽰转换也叫做强制转换。
例如:double类型转换成int类型,如int num1 = 3.14(3.14默认为double类型)int是整数型,是不带⼩数点的,然⽽在double类型中是带⼩数点之后两位的,如果要想让这⾏代码成⽴,则需要强制转换,在不同的程序语⾔中有不同的⽅法,这⾥是⽤java语⾔来说明的,int num1 =(int)3.14;只要如此写,在程序中这⾏代码就可以运⾏。
精度丢失:然⽽在这样情况下,会出现⼀个⽐较常见的问题,也是经常会遇见的错误,精度丢失,就是3.14double类型的转换到int类型之后,就只剩下了⼀个3,变为整数型。
【主题】Oracle中的Convert参数详解【内容】1. 介绍Oracle中的Convert参数在Oracle数据库中,Convert参数是一个常用的函数,主要用于将一个数据类型转换为另一个数据类型。
通过Convert参数,我们可以在查询过程中对数据类型进行转换,满足不同的需求。
2. Convert参数的语法在Oracle中,Convert参数的语法如下:CONVERT (expression, datatype)其中,expression表示要进行转换的数据,datatype表示要转换成的数据类型。
通过这个语法,我们可以灵活地进行数据类型的转换操作。
3. Convert参数的使用方法使用Convert参数非常简单,只需要在需要进行数据类型转换的地方,将需要转换的数据和目标数据类型作为参数传入即可。
下面是一个简单的示例:SELECT CONVERT('12345', NUMBER) FROM dual;这个示例中,我们将一个字符类型的数据'12345'转换为数字类型。
通过Convert参数,我们可以方便地实现数据类型之间的转换。
4. Convert参数的常见应用场景Convert参数通常用于以下几个常见的应用场景:- 数据类型转换:在数据库查询过程中,有时候需要将一个数据类型转换为另一个数据类型,这时候就可以使用Convert参数来实现。
- 数据格式转换:有时候我们需要对日期、时间等数据进行格式转换,将其转换为特定的格式,这时候也可以使用Convert参数来完成。
- 数据单位转换:在一些业务场景中,可能需要将数据的单位进行转换,比如将温度由摄氏度转换为华氏度,这时候也可以使用Convert参数来实现。
5. Convert参数的注意事项在使用Convert参数时,需要注意以下几点:- 数据类型兼容性:在进行数据类型转换时,需要确保目标数据类型与原数据类型是兼容的,否则可能会出现转换失败的情况。
oraclecast函数用法Oracle的CAST函数是用来将一个表达式转换为指定的数据类型。
它可以在SELECT、INSERT、UPDATE和DELETE语句中使用。
语法如下:```CAST (expression AS data_type)```expression是需要转换的表达式,data_type是转换的目标数据类型。
Oracle中支持的数据类型包括数字类型、字符类型、日期类型等。
下面详细介绍一些常见的使用情况。
1.数字类型转换:-将字符类型转换为数字类型:```SELECTCAST('123'ASNUMBER)FROMDUAL;```结果为:123-将日期类型转换为数字类型:```SELECTCAST(SYSDATEASNUMBER)FROMDUAL;```结果为:转换为对应的数值类型,时间戳在Oracle中是以1970年1月1日午夜(GMT)以来的秒数表示的。
2.字符类型转换:-将数字类型转换为字符类型:```SELECTCAST(123ASVARCHAR2(10))FROMDUAL;```结果为:'123'-将日期类型转换为字符类型:```SELECTCAST(SYSDATEASVARCHAR2(10))FROMDUAL;```结果为:转换为指定格式的字符串,根据当前NLS_DATE_FORMAT的设置来确定日期格式。
3.日期类型转换:-将字符类型转换为日期类型:```SELECTCAST('2024-01-01'ASDATE)FROMDUAL;```结果为:2024-01-01-将数字类型转换为日期类型:``````结果为:2024-01-014.其他类型转换:-将字符串类型转换为CLOB类型:```SELECT CAST('Hello' AS CLOB) FROM DUAL;```-将BLOB类型转换为RAW类型:```SELECTCAST(BLOB_COLUMNASRAW)FROMTABLE_NAME;```需要注意的是,转换时要保证数据的格式是能够转换的,否则会报错。
列举隐式类型转换在计算机编程中,类型转换是指将数据从一种数据类型转换为另一种数据类型的过程。
其中,隐式类型转换(也称为自动类型转换或类型提升)是一种不需要程序员明确指定就能自动进行的类型转换。
当在程序中进行操作数类型不同的运算时,编译器会根据一定的规则自动将它们转换成同一种类型,然后再进行计算。
隐式类型转换虽然方便了编程,但也可能导致一些不易察觉的错误,因此了解其原理和规则对于编写健壮的程序至关重要。
一、隐式类型转换的基本原理隐式类型转换主要发生在以下几种情况:1. 算术运算中的类型提升:当两个不同数据类型的操作数进行算术运算(如加、减、乘、除)时,系统会将它们转换成同一种数据类型,通常是更宽或更精确的类型,以避免数据丢失或截断。
例如,在C++中,如果一个int类型和一个double 类型的数进行加法运算,那么int类型的数会被隐式转换成double类型,然后进行加法运算。
2. 赋值操作中的类型转换:当一个值被赋给一个不同类型的变量时,如果该值能够无损地转换成目标类型,那么隐式类型转换就会发生。
例如,在Java中,将一个byte类型的值赋给一个int类型的变量时,byte值会被隐式转换成int类型。
3. 函数调用中的参数传递:在函数调用时,如果实参的类型和形参的类型不匹配,但实参类型可以隐式转换成形参类型,那么编译器会自动进行类型转换。
这种转换通常遵循与赋值操作相同的规则。
4. 类型转换操作符的省略:在某些编程语言中,尽管存在显式的类型转换操作符,但编译器仍然会在某些情况下自动进行类型转换。
这种情况下,虽然程序员没有明确使用类型转换操作符,但编译器仍然会执行隐式类型转换。
二、隐式类型转换的规则隐式类型转换的规则因编程语言而异,但大多数编程语言都遵循类似的规则。
以下是一些常见编程语言中隐式类型转换的规则:1. C/C++中的隐式类型转换:* 整数类型之间的转换遵循整数提升规则,较小的整数类型(如char、short)会隐式转换成较大的整数类型(如int、long)。
Oracle显式游标和隐式游标SQL是用于访问Oracle数据库旳语言,PL/SQL扩展和加强了SQL旳功能,它同步引入了更强旳程序逻辑, 下面在本文中将对游标旳使用进行一下解说,但愿可以和大伙共同窗习进步。
游标字面理解就是游动旳光标。
游标是SQL旳一种内存工作区,由系统或顾客以变量旳形式定义。
在某些状况下,需要把数据从寄存在磁盘旳表中调到计算机内存中进行解决,最后将解决成果显示出来或最后写回数据库。
这样数据解决旳速度才会提高,否则频繁旳磁盘数据互换会减少效率。
用数据库语言来描述游标就是映射在成果集中一行数据上旳位置实体,有了游标,顾客就可以访问成果集中旳任意一行数据了,将游标放置到某行后,即可对该行数据进行操作,例如提取目前行旳数据等。
游标有两种类型:显式游标和隐式游标。
游标一旦打开,数据就从数据库中传送到游标变量中,然后应用程序再从游标变量中分解出需要旳数据,并进行解决。
当系统使用一种隐式游标时,可以通过隐式游标旳属性来理解操作旳状态和成果,进而控制程序旳流程。
隐式游标可以使用名字SQL来访问,但要注意,通过SQL游标名总是只能访问前一种解决操作或单行SELECT操作旳游标属性。
因此一般在刚刚执行完操作之后,立虽然用SQL游标名来访问属性。
游标旳属性有四种,分别是SQL %ISOPEN,SQL %FOUND,SQL %NOTFOUND,SQL %ROWCOUNT。
SQL%ISOPEN返回旳类型为布尔型,判断游标与否被打开,如果打开%ISO PEN等于true,否则等于false,即执行过程中为真,结束后为假。
SQL%NOTFOUND返回值为布尔型,判断游标所在旳行与否有效,如果有效,则%FOUNDD等于true,否则等于false,即与%FOUND属性返回值相反。
SQL%FOUND返回值旳类型为布尔型,值为TRUE代表插入删除更新或单行查询操作成功。
SQL%ROWCOUNT返回值类型为整型,返回目前位置为止游标读取旳记录行数,即成功执行旳数据行数。
Oracle中to_char和to_number和to_date教程在Oracle数据库中,to_char,to_number和to_date是三个非常常用的函数。
它们分别用于将不同类型的数据转换为字符型、数字型和日期型数据。
下面将逐一介绍它们的用法。
1. to_char函数to_char函数用于将不同类型的数据转换为字符型数据。
其基本语法如下:```to_char(expression, 'format')```expression是要转换的数据,可以是数字、日期等类型的数据。
'format'是转换后的字符型数据的格式。
to_char函数最常用的应用场景是将日期型数据转换为字符型数据。
例如,将日期型数据转换为指定格式的字符串:```SELECT to_char(sysdate, 'YYYY-MM-DD') FROM dual;```上述示例中,sysdate表示当前的日期,'YYYY-MM-DD'表示想要得到的日期格式。
该语句将返回当前日期的字符型数据,格式为YYYY-MM-DD。
除了日期型数据,to_char函数也可以将其他类型的数据转换为字符型数据,并指定转换后的格式。
例如,将数字转换为带千分位的字符串:``````2. to_number函数to_number函数用于将字符型数据转换为数字型数据。
其基本语法如下:```to_number(expression, 'format')```expression是要转换的字符型数据,'format'是转换后的数字型数据的格式。
to_number函数最常用的应用场景是将字符型数据转换为数字型数据。
例如,将字符型数据转换为整数:``````如果要将带有小数的字符串转换为浮点数或双精度数,则可以使用to_number函数。
例如:```SELECT to_number('3.14') FROM dual;```上述示例中,'3.14'是要转换的字符型数据。
2)to_date字符值->日期值语法:to_date (string,[format mask],[nls_parameters])参数:string 待转换的字符值format mask:可选参数格式掩码同to_char转换为date时相同。
备注:转换时要根据给定的string设定正确的格式掩码,否则Ora_01840:input value is not long enough for date format.Ora_01862:the numeric value does not match the length of the format item. 3)to_number字符值->数字值语法:to_number (string,[format mask],[nls_parameters])参数:string 待转换的字符值format mask:可选参数格式掩码同to_char转换为number时相同。
备注:如果使用较短的格式掩码就会返回错误。
例如: to_number(123.56,’999.9’)返回错误。
在oracle中,如果不同的数据类型之间关联,如果不显式转换数据,则它会根据以下规则对数据进行隐式转换1) 对于INSERT和UPDATE操作,oracle会把插入值或者更新值隐式转换为字段的数据类型。
假如id列的数据类型为numberupdate t set id='1'; -> 相当于 update t set id=to_number('1');insert into t(id) values('1') -> insert into t values(to_number('1'));2) 对于SELECT语句,oracle会把字段的数据类型隐式转换为变量的数据类型。
如假设id列的数据类型为varchar2select * from t where id=1; -> select * from t where to_number(id)=1;但如果id列的数据类型为number,则select * from t where id='1'; -> select * from t where id=to_number('1');(参考下文)3) 当比较一个字符型和数值型的值时,oracle会把字符型的值隐式转换为数值型。
Oracle中的数据类型和数据类型之间的转换Oracle中的数据类型/*ORACLE 中的数据类型;char 长度固定范围:1-2000VARCHAR2 长度可变范围:1-4000LONG 长度可变最⼤的范围2gb 长字符类型number 数字 number(p,s)Date ⽇期类型,精确到秒TIMESTAMP 存储⽇期,时间,时区,妙值,精确到⼩数CLOB 字符数据BLOB 存放⼆进制数据,视频图⽚等BFILE :⽤于将⼆进制数据存储在数据库外部的操作系统⽂件中所谓固定长度:所谓固定长度:是指虽然输⼊的字段值⼩于该字段的限制长度,但是实际存储数据时,会先⾃动向右补⾜空格后,才将字段值的内容存储到数据块中。
这种⽅式虽然⽐较浪费空间,但是存储效率较可变长度类型要好。
同时还能减少数据⾏迁移情况发⽣。
所谓可变长度:是指当输⼊的字段值⼩于该字段的限制长度时,直接将字段值的内容存储到数据块中,⽽不会补上空⽩,这样可以节省数据块空间。
*/--储字节或字符?CREATE TABLE T1(NAME CHAR(4) --默认的是字节);INSERT INTO T1 VALUES('AB');INSERT INTO T1 VALUES('ABCD');INSERT INTO T1 VALUES('我爱中国'); --这个就会报错INSERT INTO T1 VALUES('我爱'); --这样就是正确滴呀SELECT*FROM T1;SELECT LENGTH(ltrim(rtrim(NAME))) FROM T1 WHERE NAME='AB'--2SELECT LENGTH(NAME) FROM T1 WHERE NAME='AB'--4SELECT NAME FROM T1 WHERE NAME=N'AB'; --没有值滴呀;SELECT NAME FROM T1 WHERE NAME='AB';--同样的⽐较;CREATE TABLE T2(NAME CHAR(4CHAR) --默认的是字节);INSERT INTO T2 VALUES('ABCD');INSERT INTO T2 VALUES('ABCDABCD'); --报错INSERT INTO T2 VALUES('我爱中国'); ----正常插⼊SELECT*FROM T2;--⼀个汉字占⼏个字符,具体的还要看编码⽅式/*数据库的NLS_CHARACTERSET 为AL32UTF8,即⼀个汉字占⽤三到四个字节。
SQL进阶-隐式类型转换⼀、隐式类型转换1、隐式类型转换隐式类型转换:SELECT1+'1';程序可读性差,且依赖数据库的隐式转换规则,如果数据库升级,则程序可能⽆法正确执⾏;有可能会导致索引失效;有可能会导致意想不到的结果;显式类型转换:SELECT1+CAST('1'AS SIGNED INT);尽量⽤显式类型转换;2、数值型 + 字符型SELECT1+'1'; 结果:2SELECT CONCAT('北京',2008); 结果:北京2008SELECT'北京'+2008; 结果:2008SELECT'HELLO '+'WORLD!'; 结果:03、隐式类型转换导致索引失效##CREATE TABLE teacher(teacher_id VARCHAR(50),teacher_name VARCHAR(50),id_no VARCHAR(50));CREATE INDEX idx_teacher_id ON teacher(teacher_id);##CREATE TABLE student(student_id INT,student_name VARCHAR(50),teacher_id INT);CREATE INDEX idx_teacher_id ON student(teacher_id);##SELECT*FROM student aINNER JOIN teacher bON a.teacher_id = b.teacher_id;此时不会⾛索引,因为在teacher表中,teacher_id是varchar类型,⽽student表中teacher_id是int类型,会做隐式类型转换,把varchar转为int类型;4、隐式类型转换导致意想不到的结果##依据上⾯的建表语句,建表并插⼊以下数据:INSERT INTO teacher VALUES('20180204060001','李斌','530102************');INSERT INTO teacher VALUES('20180204060002','张成','530102************');以下语句会返回两条结果,因为teacher_name是varchar型的,要先转为int型,varchar转int型就变成了0SELECT COUNT(*) FROM teacher WHERE teacher_name =0;||(等价)SELECT COUNT(*) FROM teacher WHERE CAST(teacher_name AS SIGNED INT) =0;这种操作还是很危险的,因为当执⾏删除语句时,可能会删错;DELETE FROM teacher WHERE teacher_name =0;##SELECT COUNT(*) FROM teacher WHERE teacher_name =0;为什么不是等价于:SELECT COUNT(*) FROM teacher WHERE teacher_name='0';因为隐式类型转换时,转的是左边⽽不是右边;##以下语句会返回两条信息,⽽不是⼀条,因为530102************这串数字,已经超过了int类型的范围,超过了int类型的范围就会转为float类型,等号两边都转为float类型,会丢精度,也就是最后⼀位数丢了,剩下的就相等了,就全返回了;SELECT COUNT(*) FROM teacher WHERE id_no =530102************;等价于:SELECT COUNT(*) FROM teacher WHERECAST(id_no AS DECIMAL) =CAST(530102************AS DECIMAL);在查询时把530102************加上单引号就可以了;5、其他数据库转换导致意想不到的结果在Teradata数据库中:SELECT10/4; 结果:2解决:可以把分母分⼦乘以1.00,再运算SELECT COUNT(*) FROM table1; count返回的是int类型,如果表中数据量超过count出来的数,就报错解决:在count(*) 外⾯cast转换⼀下,转换为能保存结果的类型。
备注:转换时要根据给定的string设定正确的格式掩码,否则
Ora_01840:input value is not long enough for date format.
Ora_01862:the numeric value does not match the length of the format item.
3) to_number
字符值->数字值
语法:to_number (string,[format mask],[nls_parameters])
参数:string 待转换的字符值
format mask:可选参数
格式掩码同to_char转换为number时相同。
备注:如果使用较短的格式掩码就会返回错误。
例如: to_number(123.56,’999.9’)返回错误。
在oracle中,如果不同的数据类型之间关联,如果不显式转换数据,则它会根据以下规则对数据进行隐式转换
1) 对于INSERT和UPDATE操作,oracle会把插入值或者更新值隐式转换为字段的数据类型。
假如id列的数据类型为number
update t set id='1'; -> 相当于update t set id=to_number('1');
insert into t(id) values('1') -> insert into t values(to_number('1'));
2) 对于SELECT语句,oracle会把字段的数据类型隐式转换为变量的数据类型。
如假设id列的数据类型为varchar2
select * from t where id=1; -> select * from t where to_number(id)=1;
但如果id列的数据类型为number,则
select * from t where id='1'; -> select * from t where id=to_number('1');(参考下文)
3) 当比较一个字符型和数值型的值时,oracle会把字符型的值隐式转换为数值型。
如假设id列的数据类型为number
select * from t where id='1'; -> select * from t where id=to_number('1');
4) 当比较字符型和日期型的数据时,oracle会把字符型转换为日期型。
如假设create_date为字符型,
select * from t where create_date>sysdate; -> select * from t where
to_date(create_date)>sysdate;(注意,此时session的nls_date_format需要与字符串格式相符)假设create_date为date型,
select * from t where create_date>'2006-11-11 11:11:11'; -> select * from t
where create_date>to_date('2006-11-11 11:11:11'); (注意,此时session的nls_date_format 需要与字符串格式相符)
5) 如果调用函数或过程等时,如果输入参数的数据类型与函数或者过程定义的参数数据类型不一直,则oracle会把输入参数的数据类型转换为函数或者过程定义的数据类型。
如假设过程如下定义p(p_1 number)
exec p('1'); -> exec p(to_number('1')); 6)
赋值时,oracle会把等号右边的数据类型转换为左边的数据类型。
如var a number a:='1'; - > a:=to_number('1');
7) 用连接操作符(||)时,oracle会把非字符类型的数据转换为字符类型。
select 1||'2' from dual; -> select to_char(1)||'2' from dual;
8) 如果字符类型的数据和非字符类型的数据(如number、date、rowid等)作算术运算,则oracle 会将字符类型的数据转换为合适的数据类型,这些数据类型可能是number、date、rowid等。
如果CHAR/VARCHAR2 和NCHAR/NVARCHAR2之间作算术运算,
则oracle会将她们都转换为number类型的数据再做比较。
9) 比较CHAR/VARCHAR2 和NCHAR/NVARCHAR2时,如果两者字符集不一样,则默认的转换方式是将数据编码从数据库字符集转换为国家字符集。
简单总结:
比较时,一般是字符型转换为数值型,字符型转换为日期型
算术运算时,一般把字符型转换为数值型,字符型转换为日期型连接时(||),一般是把数值型转换为字符型,日期型转换为字符型赋值、调用函数时,以定义的变量类型为准。