数据类型转换
在编写一个表达式或指定一个操作,目标应该使用兼容的数据类型对于操作数。当需要使用混合的数据类型发生时,它提示应该寻找一种方式转换不兼容的操作数在对它们进行操作之前。转换数据的能力很可能是一个问题,如果你正在与方言1数据。
CAST 函数使许多成对的数据类型之间显式转换。
语法:
CAST ( { <value> | NULL } AS <data_type>)
<data_type> ::= sql_datatype |
[TYPE OF] domain |
TYPE OF COLUMN relname.colname
转换到域(Domain)
当你转换到域时,声明它的的任何约束都被考虑在内,即NOT NULL或CHECK约束。如果在<value>没有通过检查,转换将失败。
如果另外指定了TYPE OF强制转换为其基类型,那么转换时任何域约束被忽略,如果TYPE OF同字符类型 (CHAR/VARCHAR) 一起使用,将保留的字符集和排序规则。
转换到TYPE OF COLUMN
当操作数强制转换为列的类型时,指定的列可以来自一个表或一个视图。
只有列本身的类型被使用。对于字符类型,转换还包括字符集,但不是排序。源列的约束和默认值并不适用。
例如:
CREATE TABLE TTT (
S VARCHAR (40)
CHARACTER SET UTF8 COLLATE UNICODE_CI_AI);
COMMIT;
SELECT
CAST ('I have many friends' AS TYPE OF COLUMN TTT.S)
FROM RDB$DATABASE;
CAST 函数可能的转换
表3.6. 用CAST转换
源数据类型 | 目标数据类型 |
Numeric types | Numeric types, [VAR]CHAR, BLOB |
[VAR]CHAR | [VAR]CHAR, BLOB, Numeric types, DATE, TIME, TIMESTAMP |
BLOB | [VAR]CHAR, BLOB, Numeric types, DATE, TIME, TIMESTAMP |
DATE, TIME | [VAR]CHAR, BLOB, TIMESTAMP |
TIMESTAMP | [VAR]CHAR, BLOB, DATE, TIME |
重要
请记住,可能会丢失部分信息。例如,当转换TIMESTAMP数据类型到DATE数据类型,时间部分被丢失。
文字格式
要转换的字符串数据类型为日期、 时间戳数据类型,需要字符串参数为预定义的日期和时间文本之一(见表 3.7)或日期表示形式为被允许的日期时间文本格式之一:
<datetime_literal> ::= {
[YYYY<p>]MM<p>DD[<p>HH[<p>mm[<p>SS[<p>NNNN]]]] |
MM<p>DD[<p>YYYY[<p>HH[<p>mm[<p>SS[<p>NNNN]]]]] |
DD<p>MM[<p>YYYY[<p>HH[<p>mm[<p>SS[<p>NNNN]]]]] |
MM<p>DD[<p>YY[<p>HH[<p>mm[<p>SS[<p>NNNN]]]]] |
DD<p>MM[<p>YY[<p>HH[<p>mm[<p>SS[<p>NNNN]]]]] |
NOW |
TODAY |
TOMORROW |
YESTERDAY
}
<date_literal> ::= {
[YYYY<p>]MM<p>DD |
MM<p>DD[<p>YYYY] |
DD<p>MM[<p>YYYY] |
MM<p>DD[<p>YY] |
DD<p>MM[<p>YY] |
TODAY |
TOMORROW |
YESTERDAY
}
<time_literal> := HH[<p>mm[<p>SS[<p>NNNN]]]
<p> ::= whitespace | . | : | , | - | /
表 3.7. 日期时间文本格式参数
参数 | 描述 |
datetime_literal | 日期和时间文本 |
time_literal | 时间文本 |
date_literal | 日期文本 |
YYYY | 4位数字年 |
YY | 2位数字年 |
MM | 月.可能包含1位或2位数字(1-12 或01-12). 您还可以指定三个字母的缩写名称或英文某个月的全名. 大小写不敏感 |
DD | 日. 可能包含1位或2位数字(1-31 或01-31) |
HH | 小时. 可能包含1位或2位数字 (0-23 或 00-23) |
mm | 分钟. 可能包含1位或2位数字 (0-59 或 00-59) |
SS | 秒. 可能包含1位或2位数字 (0-59 或 00-59) |
NNNN | 万分之秒. 可能包含从1-4位数字 (0-9999) |
p | 分隔符,任何字符都可以,前置和后置空被忽略 |
表3.8. 日期和时间有预定义值的文本
文本 | 描述 | 数据类型 | |
方言1 | 方言3 | ||
'NOW’ | 当前的日期和时间 | DATE | TIMESTAMP |
'TODAY' | 当前的日期 | DATE 带上0时间 | DATE |
'TOMORROW' | 当前的日期 +1(天) | DATE 带上0时间 | DATE |
'YESTERDAY' | 当前的日期 -1(天) | DATE 带上0时间 | DATE |
重要
强烈推荐使用年的四位数形式的完整规范 — — YYYY ,为避免日期在计算和聚合方面的混淆。
示例日期字面解释:
select
cast('04.12.2014' as date) as d1, -- DD.MM.YYYY
cast('04 12 2014' as date) as d2, -- MM DD YYYY
cast('4-12-2014' as date) as d3, -- MM-DD-YYYY
cast('04/12/2014' as date) as d4, -- MM/DD/YYYY
cast('04,12,2014' as date) as d5, -- MM,DD,YYYY
cast('04.12.14' as date) as d6, -- DD.MM.YY
-- DD.MM with current year
cast('04.12' as date) as d7,
-- MM/DD with current year
cast('04/12' as date) as d8,
cast('2014/12/04' as date) as d9, -- YYYY/MM/DD
cast('2014 12 04' as date) as d10, -- YYYY MM DD
cast('2014.12.04' as date) as d11, -- YYYY.MM.DD
cast('2014-12-04' as date) as d12, -- YYYY-MM-DD
cast('4 Jan 2014' as date) as d13, -- DD MM YYYY
cast('2014 Jan 4' as date) as dt14, -- YYYY MM DD
cast('Jan 4, 2014' as date) as dt15, -- MM DD, YYYY
cast('11:37' as time) as t1, -- HH:mm
cast('11:37:12' as time) as t2, -- HH:mm:ss
cast('11:31:12.1234' as time) as t3, -- HH:mm:ss.nnnn
cast('11.37.12' as time) as t4, -- HH.mm.ss
-- DD.MM.YYYY HH:mm
cast('04.12.2014 11:37' as timestamp) as dt1,
-- MM/DD/YYYY HH:mm:ss
cast('04/12/2014 11:37:12' as timestamp) as dt2,
-- DD.MM.YYYY HH:mm:ss.nnnn
cast('04.12.2014 11:31:12.1234' as timestamp) as dt3,
-- MM/DD/YYYY HH.mm.ss
cast('04/12/2014 11.37.12' as timestamp) as dt4
from rdb$database
为日期和时间数据类型简写强制转换
Firebird数据库允许一种简写"C-style"类型语法用于从字符串转换为日期,时间和时间戳类型。
语法:
data_type 'date_literal_string'
例子:
-- 1
UPDATE PEOPLE
SET AGECAT = 'SENIOR'
WHERE BIRTHDATE < DATE '1-Jan-1943';
-- 2
INSERT INTO APPOINTMENTS
(EMPLOYEE_ID, CLIENT_ID, APP_DATE, APP_TIME)
VALUES (973, 8804, DATE 'today' + 2, TIME '16:00');
-- 3
NEW.LASTMOD = TIMESTAMP 'now';
备注
这些简写表达式在分析阶段直接求值,仿佛是为执行早已准备好的语句。因此,即使运行查询多次的值,例如,时间戳'now' 仍然是一样的无论经过多少时间。
如果需要在每个执行中进行时间求值,使用完整的语法。使用这样的一个表达式在触器中的一个例子:
NEW.CHANGE_DATE = CAST('now' AS TIMESTAMP);