

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# CAST
<a name="sql-reference-cast"></a>

CAST 允许您将一种值表达式或数据类型转换为另一种值表达式或数据类型。

```
CAST ( <cast-operand> AS <cast-target> )
 <cast-operand> := <value-expression>
 <cast-target>  := <data-type>
```

## 有效转换
<a name="w2aac22c15c11b7"></a>

对下面第一列中列出的源运算对象类型使用 CAST，可以创建第二列中列出的转换目标类型，没有任何限制。不支持其他目标类型。


| 源运算对象类型 | 目标运算对象类型 | 
| --- | --- | 
|  任何数字类型（NUMERIC、DECIMAL、SMALLINT、INTEGER、BIGINT、REAL、DOUBLE）  |  VARCHAR、CHAR 或任何数字类型（参阅注释 A。）  | 
|  VARCHAR、CHAR  |  以上全部，再加上 DATE、TIME、TIMESTAMP、DAY-TIME INTERVAL、BOOLEAN  | 
|  DATE  |  DATE、VARCHAR、CHAR、TIMESTAMP  | 
|  TIME  |  TIME、VARCHAR、CHAR、TIMESTAMP  | 
|  TIMESTAMP  |  TIME、VARCHAR、CHAR、TIMESTAMP、DATE  | 
|  DAY-TIME INTERVAL  |  DAY-TIME INTERVAL、BIGINT、DECIMAL、CHAR、VARCHAR  | 
|  BOOLEAN  |  VARCHAR、CHAR、BOOLEAN  | 
|  BINARY、VARBINARY  |  BINARY、VARBINARY  | 

### 示例
<a name="sql-reference-cast-exmaples"></a>

#### 2.1 将 DATE 转换为 CHAR/VARCHAR
<a name="w2aac22c15c11b7b6b2"></a>

```
+-------------+
|   EXPR$0    |
+-------------+
| 2008-08-23  |
+-------------+
1 row selected
```

（请注意，如果提供的输出规范不充分，则不会选择任何行：

```
values(cast(date'2008-08-23' as varchar(9)));
'EXPR$0'
No rows selected
```

（因为日期文字需要包含 10 个字符）

在下一个示例中，日期的右侧填充的是空白（由于 CHAR 数据类型的语义）：

```
+----------------------------+
|           EXPR$0           |
+----------------------------+
| 2008-08-23                 |
+----------------------------+
1 row selected
```

#### 将 REAL 转换为 INTEGER
<a name="w2aac22c15c11b7b6b4"></a>

实数（NUMERIC 或 DECIMAL）在转换时会四舍五入：

```
+---------+
| EXPR$0  |
+---------+
| -2      |
+---------+
1 row selected
```

#### 将 STRING 转换为 TIMESTAMP
<a name="w2aac22c15c11b7b6b6"></a>

将字符串转换为时间戳的方式有两种。第一种是使用 CAST，如下一个主题所示。另一种是使用 [Char To Timestamp(Sys)](sql-reference-char-to-timestamp.md)。

## 使用 CAST 将字符串转换为时间戳
<a name="w2aac22c15c11b9"></a>

以下示例说明了这种转换方法：

```
'EXPR$0'
'2007-02-19 21:23:45'
1 row selected
```

如果输入字符串缺少六个字段（年、月、日、时、分、秒）中的任何一个，或者使用了任何与上述不同的分隔符，则 CAST 将不会返回值。（不允许使用小数秒。）

因此，如果输入字符串的格式不适合 CAST，则要将该字符串转换为时间戳，必须使用 CHAR\$1TO\$1TIMESTAMP 方法。

## 使用 CHAR\$1TO\$1TIMESTAMP 将字符串转换为时间戳
<a name="BOOTSTRINGTOTIMESTAMP"></a>

当输入字符串的格式不适合 CAST 时，可以使用 CHAR\$1TO\$1TIMESTAMP 方法。该方法的另一个优点是，您可以指定要在后续处理中使用时间戳字符串的哪些部分，并创建一个仅包含这些部分的 TIMESTAMP 值。为此，您需要指定一个模板来标识所需部分，例如“yyyy-MM”，以便仅使用年和月这两个部分。

 input-date-time string-to-be-converted可以包含完整时间戳的全部或任何部分，即任何或全部标准元素的值（'yyyy-MM-dd hh: mm: ss'）。如果所有这些元素都存在于您的输入字符串中，并且您提供的模板是 'yyyy-MM-dd hh: mm: ss'，则输入字符串元素将按该顺序解释为年、月、日、时、分和秒，例如 '2009-09-16 03:15:24 '。yyyy 不能大写；hh 可以大写，表示使用 24 小时制。有关有效说明符的许多示例，请参阅本主题后面的表格和示例。有关所有有效说明符的信息，请参阅 Oracle 网站 SimpleDateFormat上的[类别](http://docs.oracle.com/javase/7/docs/api/index.html?java/text/SimpleDateFormat.html)。

CHAR\$1TO\$1TIMESTAMP 使用您指定的模板作为函数调用中的参数。该模板使 TIMESTAMP 结果仅使用您在模板中指定的部分 input-date-time值。然后，生成的 TIMESTAMP 中的这些字段将包含从您的 input-date-time字符串中提取的相应数据；模板中未指定的字段将使用默认值（见下文）。CHAR\$1TO\$1TIMESTAMP 使用的模板格式由 [Class](http://docs.oracle.com/javase/7/docs/api/index.html?java/text/SimpleDateFormat.html) 定义 SimpleDateFormat，其中列出了所有说明符，其中一些带有示例。有关更多信息，请参阅[日期和时间模式](sql-reference-parse-timestamp-format.md)。

函数调用语法如下：

```
  CHAR_TO_TIMESTAMP('<format_string>','<input_date_time_string>')
```

其中，<format\$1 string> 是您为所需的 <date\$1time\$1string> 部分指定的模板，<input\$1date\$1time\$1string> 是将转换为 TIMESTAMP 结果的原始字符串。

每个字符串必须用单引号引起来，并且 <input\$1date\$1time\$1string> 的每个元素必须位于其在模板中的相应元素的范围内。否则，不返回任何结果。

### 示例 1
<a name="sql-reference-cast-example-1"></a>
+ 位置 input-string-element与 MM 对应的，必须是介于 1 到 12 之间的整数，因为其他任何东西都不能代表有效的月份。
+ 位置 input-string-element与 dd 对应的，必须是介于 1 到 31 之间的整数，因为其他任何东西都不能代表有效的日期。
+ 但是，如果 MM 为 2，则 dd 不能是 30 或 31，因为 2 月没有这几日。

但是，对于月或日，替换省略部分的默认起始值为 01。

例如，使用“2009-09-16 03:15:24”作为输入字符串，您可以获得仅包含日期的 TIMESTAMP，其他字段（例如时、分或秒）为零，方法是指定以下内容：

```
  CHAR_TO_TIMESTAMP('yyyy-MM-dd','2009-09-16 03:15:24').
```

结果将是 TIMESTAMP 2009-09-16 00:00:00。

### 示例 2
<a name="sql-reference-cast-example-2"></a>
+ 如果呼叫在模板中保留了小时和分钟，同时省略了月、天和秒，如以下调用所示-----CHAR\$1TO\$1TIMESTAMP (', '2009-09-16 03:15:24yyyy-hh-mm')-----那么生成的时间戳将是 2009-01-01 03:15:00。


| 模板 | 输入字符串 | 输出TIMESTAMP | 注意 | 
| --- | --- | --- | --- | 
|  'yyyy-MM-dd hh:mm:ss'  |  '2009-09-16 03:15:24'  |  '2009-09-16 03:15:24'  |  输入字符串必须使用 “yyyy-MM-dd hh: mm: ss” 的形式或其子集或重新排序；使用像 “2009 年 9 月 16 日星期三 03:15:24” 这样的输入字符串将不起作用，这意味着不会产生任何输出。  | 
|  'yyyy-mm'  |  '2012-02-08 07:23:19'  |  '2012-01-01 00:02:00'  | 上面的模板仅指定了第一个是年和第二个是分，因此输入字符串中的第二个元素（“02”）用作分。 月和日使用默认值（“01”），时和秒使用默认值（“00”）。 | 
|  'yyyy-ss-mm'  |  '2012-02-08 07:23:19'  |  '2012-01-01 00:08:02'  | 上面的模板仅指定了年、秒和分，按照该顺序，因此输入字符串中的第二个元素（“02”）用作秒，第三个元素（“08”）用作分。月和日使用默认值（“01”），时使用默认值（“00”）。 | 
|  'MMM dd, yyyy'  |  'March 7, 2010'  |  '2010-03-07 00:00:00'  | 上面模板中的 MMM 与“March”匹配；模板的“逗号空格”与输入字符串匹配。 --- --- 如果模板缺少逗号，输入字符串也必须缺少逗号，否则就没有输出； --- --- 如果输入字符串缺少逗号，模板也必须缺少逗号。 | 
|  'MMM dd,'  |  'March 7, 2010'  |  '1970-03-07 00:00:00'  | 请注意，上面的模板没有使用年说明符，这会导致输出 TIMESTAMP 使用这个时代最早的一年，即 1970。 | 
|  'MMM dd,y'  |  'March 7, 2010'  |  '2010-03-07 00:00:00'  | 使用上面的模板，如果输入字符串是“March 7, 10”，则输出 TIMESTAMP 将是“0010-03-07 00:00:00”。 | 
|  'M-d'  |  '2-8'  |  '1970-02-08 00:00:00'  | 如上所示，模板中没有 yyyy 说明符，因此使用这个时代最早的一年 (1970)。 输入字符串“2-8-2012”将生成相同的结果；使用“2012-2-8”不会生成任何结果，因为 2012 不是有效的月。 | 
|  'MM-dd-yyyy'  |  '06-23-2012 10:11:12'  |  '2012-06-23 00:00:00'  | 如果模板和输入都在相同位置使用短划线作为分隔符（如上所示），则可以使用短划线。由于模板省略了时、分和秒，因此在输出 TIMESTAMP 中都使用零。 | 
|  'dd-MM-yy hh:mm:ss'  |  '23-06-11 10:11:12'  |  '2011-06-23 10:11:12'  |  您可以按任意顺序使用这些说明符，但前提是该顺序与您提供的输入字符串的含义匹配，如上所示。下面下一个示例的模板和输入字符串与此示例具有相同的含义（和相同的输出 TIMESTAMP），但在日之前指定了月，在时之前指定了秒。  | 
|  'MM-dd-yy ss:hh:mm'  |  '06-23-11 12:10:11'  |  '2011-06-23 10:11:12'  | 在上面使用的模板中，月和日说明符的顺序与上面的示例相反，秒的说明符在时之前而不是分之后；但是由于输入字符串还将月放在日之前，将秒放在时之前，因此含义（和输出 TIMESTAMP）与上面的示例相同。 | 
|  'yy-dd-MM ss:hh:mm'  |  '06-23-11 12:10:11'  |  '2006-11-23 10:11:12'  | 上面使用的模板颠倒了（与上面的前一个示例相比）年和月说明符，而输入字符串保持不变。在本例中，输出 TIMESTAMP 使用输入字符串的第一个元素作为年，第二个元素作为日，第三个元素作为月。 | 
|  'dd-MM-yy hh:mm'  |  '23-06-11 10:11:12'  |  '2011-06-23 10:11:00'  | 如上所示，模板中省略了秒，输出 TIMESTAMP 使用 00 秒。任意数量的 y 说明符都会生成相同的结果；但是如果输入字符串无意中对年使用的是 1 而不是 11，例如在“23-06-1 10:11:12”中，则输出 TIMESTAMP 将变为“0001-06-23 10:11:00”。 | 
|  'MM/dd/yy hh:mm:ss'  |  `'12/19/11 10:11:12'`  `'12/19/11 12:11:10'`  |  `'2011-12-19 10:11:12'`  `'2011-12-19 00:11:10'`  | 如果模板和输入都在相同位置使用斜杠作为分隔符（如上所示），则可以使用斜杠；否则，无输出。 使用说明符 hh，输入时间“12:11:10”和“00:11:10”与上午的时间含义相同。 | 
|  'MM/dd/yy HH:mm:ss'  |  '12/19/11 12:59:59' '12/19/11 21:08:07'  |  '2011-12-19 12:59:59' '2011-12-19 21:08:07'   | 对于此模板，输入字符串值 “2011-12-19 00:11:12” 或 “2011-12-19 12:11:12” 会失败，因为 “2011” 不是一个月，就像模板字符串 “HH: mm: ss” 那样。 required/expected MM/dd/yy但是，更改模板会生成有用的输出：<pre><br />values(cast(CHAR_TO_TIMESTAMP('y/MM/dd HH:mm:ss', '2011/12/19 00:11:12') as varchar(19)));<br />'EXPR$0'<br />'2011-12-19 00:11:12'<br />1 row selected</pre>`'12/19/11 00:11:12'` 将因上述模板 (`'y/MM/dd'`) 而失败，因为 19 不是有效月份；提供 `'12/11/19 00:11:12'` 将起作用。`'2011-12-19 12:11:12'` 作为输入时将失败，因为短划线与模板中的斜杠不符，而 `'2011/12/19 12:11:12'` 有效。 请注意，对于中午 12 点之后的时间，也就是说，对于下午和晚上的时间，时说明符必须是 HH 而不是 hh，并且输入字符串必须以 24 小时制时间指定下午或晚上的时，时从 00 到 23。 --- --- 使用说明符 HH，输入时间“12:11:10”和“00:11:10”具有不同的含义，第一个是下午的时间，第二个是上午的时间。 --- --- 使用说明符 hh，从 12:00 到 11:59:59 的时间是上午的时间： --- --- 使用说明符 hh:mm:ss，对于输入字符串“12:09:08”和“00:09:08”，输出 TIMESTAMP 都将包括上午的“00:09:08”； --- --- 而 --- --- 使用说明符 HH:mm:ss，对于上午的输入字符串“00:09:08”，输出 TIMESTAMP 将包括“00:09:08” --- --- 而对于下午的输入字符串“12:09:08”，输出 TIMESTAMP 将包括“12:09:08”。  | 

### 更多示例
<a name="sql-reference-cast-examples-further"></a>

以下示例说明了如何将各种模板与 CHAR\$1TO\$1TIMESTAMP 搭配使用，包括一些常见的误解。

```
 values (CHAR_TO_TIMESTAMP('yyyy-hh-mm','2009-09-16 03:15:24'));
'EXPR$0'
'2009-01-01 09:16:00'
1 row selected
```

请注意，上述输入字符串中的字段是按照模板中说明符给出的顺序使用的，由模板和输入字符串 dashes-as-delimiters中的定义：先是年，然后是小时，然后是分钟。由于模板中不存在月和日的说明符，因此其在输入字符串中的值被忽略，输出 TIMESTAMP 中的这两个值都替换为 01。模板指定了时和分作为第二和第三个输入值，因此 09 成为了时，16 成为了分。秒没有说明符，因此使用了 00。

年说明符可以单独使用，也可以在与输入字符串匹配的分隔符之后显示年说明符结束，其中一个是 hours:minutes:seconds 说明符：

```
values (CHAR_TO_TIMESTAMP('yyyy','2009-09-16 03:15:24') );
'EXPR$0'
'2009-01-01 00:00:00'
1 row selected
values (CHAR_TO_TIMESTAMP('yyyy hh','2009-09-16 03:15:24') );
'EXPR$0'
No rows selected
```

上面的模板失败了，因为它在输入字符串的日期规范中使用了 “hh” space-as-delimiter 之前的分隔符，而不是破折号分隔符；

而下面的四个模板之所以起作用，是因为使用相同的分隔符将年说明符与下一个说明符分隔，就像在输入字符串的日期规范中使用的那样（第一个示例中是短划线，第二个示例中是空格，第三个示例中是斜杠，第四个示例中是短划线）。

```
values (CHAR_TO_TIMESTAMP('yyyy-hh','2009-09-16 03:15:24') );
'EXPR$0'
'2009-01-01 09:00:00'
1 row selected
values (CHAR_TO_TIMESTAMP('yyyy hh','2009 09 16 03:15:24') );
'EXPR$0'
'2009-01-01 09:00:00'
1 row selected
values (CHAR_TO_TIMESTAMP('yyyy/hh','2009/09/16 03:15:24') );
'EXPR$0'
'2009-01-01 09:00:00'
1 row selected
values (CHAR_TO_TIMESTAMP('yyyy-mm','2009-09-16 03:15:24') );
'EXPR$0'
'2009-01-01 00:09:00'
1 row selected
```

但是，如果模板指定了月 (MM)，则除非还指定了日，否则将无法指定时、分或秒：

模板仅指定年份和月份，因此在生成的 TIMESTAM days/hours/minutes/seconds P 中省略了：

```
values (CHAR_TO_TIMESTAMP('yyyy-MM','2009-09-16 03:15:24') );
'EXPR$0'
'2009-09-01 00:00:00'
1 row selected
```

接下来的两个模板失败了，缺少“日”说明符：

```
values (CHAR_TO_TIMESTAMP('yyyy-MM hh','2009-09-16 03:15:24') );
'EXPR$0'
No rows selected
values (CHAR_TO_TIMESTAMP('yyyy-MM hh:','2009-09-16 03:15:24') );
'EXPR$0'
No rows selected
```

接下来的三个成功了，使用了“日”说明符：

```
 values (CHAR_TO_TIMESTAMP('yyyy-MM-dd hh','2009-09-16 03:15:24') );
'EXPR$0'
'2009-09-16 03:00:00'
1 row selected
```

上面的模板 “yyyy-MM-dd hh” 仅指定小时 (hh)，没有分钟或秒。由于 hh 是模板 token/element 的第 4 个，因此它的值将取自输入字符串 '2009-09-16 03:15:24 '的第 4 token/element 个；第 4 个元素是 03，然后用作数小时的值输出。由于未指定 mm 或 ss，因此使用定义为 mm 和 ss 起点的默认值或初始值，即零。

```
values (CHAR_TO_TIMESTAMP('yyyy-MM-dd ss','2009-09-16 03:15:24') );
'EXPR$0'
'2009-09-16 00:00:03'
1 row selected
```

上面的模板 'yyyy-MM-dd ss' 指定将输入字符串 token/element 的第 4 个用作秒 (ss)。输入字符串“2009-09-16 03:15:24”的第 4 个元素是 03，将成为模板中指定的秒的值输出；而且由于模板中未指定 hh 和 mm，因此使用默认值或初始值，即零。

```
values (CHAR_TO_TIMESTAMP('yyyy-MM-dd mm','2009-09-16 03:15:24') );
'EXPR$0'
'2009-09-16 00:03:00'
1 row selected
```

上面的模板' yyyy-MM-dd mm'指定将输入字符串 token/element 的第四个用作分钟 (mm)。输入字符串“2009-09-16 03:15:24”的第 4 个元素是 03，将成为模板中指定的分的值输出；而且由于模板中未指定 hh 和 ss，因此使用默认值或初始值，即零。

更多失败，缺少“日”说明符：

```
values (CHAR_TO_TIMESTAMP('yyyy-MM- mm','2009-09-16 03:15:24') );
'EXPR$0'
No rows selected
values (CHAR_TO_TIMESTAMP('yyyy-MM   mm','2009-09-16 03:15:24') );
'EXPR$0'
No rows selected
values (CHAR_TO_TIMESTAMP('yyyy-MM   hh','2009-09-16 03:15:24') );
'EXPR$0'
No rows selected
```

## 关于分隔符和值
<a name="w2aac22c15c11c13"></a>

模板中的分隔符必须与输入字符串中的分隔符匹配；输入字符串中的值必须是其对应的模板说明符可以接受的。

按照一般惯例，冒号用于分隔时和分以及分和秒。同样，一般惯例是使用短划线或斜杠分隔年和月以及月和日。任何并行用法似乎都行，以下示例说明了这一点。

```
values (CHAR_TO_TIMESTAMP('MM/dd/yy hh:mm:ss','2009/09/16 03:15:24') );
'EXPR$0'
No rows selected
```

上面的示例之所以失败，是因为 2009 不是可接受的月值，月是模板中的第一个说明符 (MM)。

```
values (CHAR_TO_TIMESTAMP('MM/dd/yy hh:mm:ss','09/16/11 03:15:24') );
'EXPR$0'
'2011-09-16 03:15:24'
1 row selected
```

上面的示例之所以成功，是因为分隔符是并行的（斜杠对斜杠，冒号对冒号），并且每个值对于相应的说明符都是可以接受的。

```
values (CHAR_TO_TIMESTAMP('MM/dd/yy hh/mm/ss','09/16/11 03/15/24') );
'EXPR$0'
'2011-09-16 03:15:24'
1 row selected
```

上面的示例之所以成功，是因为分隔符是并行的（所有斜杠），并且每个值对于相应的说明符都是可以接受的。

```
values (CHAR_TO_TIMESTAMP('MM/dd/yy hh-mm-ss','09/16/11 03-15-24') );
'EXPR$0'
'2011-09-16 03:15:24'
1 row selected
values (CHAR_TO_TIMESTAMP('yyyy|MM|dd hh|mm|ss','2009|09|16 03|15|24') );
'EXPR$0'
'2009-09-16 03:15:24'
1 row selected
values (CHAR_TO_TIMESTAMP('yyyy@MM@dd hh@mm@ss','2009@09@16 03@15@24') );
'EXPR$0'
'2009-09-16 03:15:24'
1 row selected
```

上面的示例之所以成功，是因为分隔符是并行的，并且值对于每个说明符都是可以接受的。

在以下示例中，请注意，提供的字符串中的省略可能会导致模板值“yyyy”生成合乎逻辑但意想不到或出乎意料的结果。在生成的 TIMESTAMP 值中作为年给出的值直接派生自所提供字符串中的第一个元素。

```
 VALUES(CHAR_TO_TIMESTAMP('yyyy','09-16 03:15'));
'EXPR$0'
'0009-01-01 00:00:00'
1 row selected
VALUES(CHAR_TO_TIMESTAMP('yyyy','16 03:15'));
'EXPR$0'
'0016-01-01 00:00:00'
1 row selected
```

## 将 TIMESTAMP 转换为 STRING
<a name="TOC6"></a>

```
 values(cast( TIMESTAMP '2007-02-19 21:25:35' AS VARCHAR(25)));
'EXPR$0'
'2007-02-19 21:25:35'
1 row selected
```

请注意，CAST 需要 timestamp-Literal 才能具有 'hh: mm: ss' 的完整格式。yyyy-mm-dd 如果缺少该完整格式的任何部分，则该文字将被视为非法而被拒绝，如下所示：

```
 values( TIMESTAMP '2007-02-19 21:25');
Error: Illegal TIMESTAMP literal '2007-02-19 21:25':
                                  not in format 'yyyy-MM-dd HH:mm:ss' (state=,code=0)
 values( TIMESTAMP '2007-02-19 21:25:00');
'EXPR$0'
'2007-02-19 21:25:00'
1 row selected
```

此外，如果提供的输出规范不充分，则不会选择任何行：

```
values(cast( TIMESTAMP '2007-02-19 21:25:35' AS VARCHAR(18)));
'EXPR$0'
No rows selected
(Because the timestamp literal requires 19 characters)
```

这些限制适用于 “时间 CASTing ” 或 “日期” 类型。

## 将 STRING 转换为 TIME
<a name="TOC7"></a>

```
 values(cast(' 21:23:45.0' AS TIME));
'EXPR$0'
'21:23:45'
1 row selected
```

有关更多信息，请参阅注释 A。

## 将 STRING 转换为 DATE
<a name="TOC8"></a>

```
 values(cast('2007-02-19' AS DATE));
'EXPR$0'
'2007-02-19'
1 row selected
```

**注释 A**  
请注意，对字符串进行 CAST 要求用于转换为 TIME 或 DATE 的字符串运算对象采用分别表示 TIME 或 DATE 所需的确切格式。

如下所示，在以下情况下，转换将失败：
+ 字符串运算对象包括与目标类型无关的数据，或者
+ INTERVAL 运算对象 ( 'day hours:minutes:seconds.milliseconds' ) 未包含必要的数据，或者
+ 指定的输出字段太小，无法保留转换结果。

```
 values(cast('2007-02-19 21:23:45.0' AS TIME));
'EXPR$0'
No rows selected
```

失败，因为包含不允许作为 TIME 的日期信息。

```
 values(cast('2007-02-19 21:23:45.0' AS DATE));
'EXPR$0'
No rows selected
```

失败，因为包含不允许作为 DATE 的时间信息。

```
 values(cast('2007-02-19 21' AS DATE));
'EXPR$0'
No rows selected
```

失败，因为包含不允许作为 DATE 的时间信息。

```
 values(cast('2009-02-28' AS DATE));
'EXPR$0'
'2009-02-28'
1 row selected
```

成功，因为包含日期字符串的正确表示形式。

```
 values(CAST (cast('2007-02-19 21:23:45.0' AS TIMESTAMP) AS DATE));
'EXPR$0'
'2007-02-19'
1 row selected
```

成功，因为在转换为 DATE 之前正确地将字符串转换为了 TIMESTAMP。



```
 values(cast('21:23' AS TIME));
'EXPR$0'
No rows selected
```

失败，因为缺少 TIME 所需的时间信息（秒）。

（允许指定小数秒，但并非必需。）



```
 values(cast('21:23:34:11' AS TIME));
'EXPR$0'
No rows selected
```

失败，因为包含不正确的小数秒表示形式。

```
 values(cast('21:23:34.11' AS TIME));
'EXPR$0'
'21:23:34'
1 row selected
```

成功，因为包含正确的小数秒表示形式。

```
 values(cast('21:23:34' AS TIME));
'EXPR$0'
'21:23:34'
1 row selected
```

此示例之所以成功，是因为包含正确的秒表示形式，而没有小数秒。

## 将 INTERVAL 转换为确切数字
<a name="TOC10"></a>

对间隔进行 CAST 要求 INTERVAL 运算对象中只有一个字段，例如 MINUTE、HOUR、SECOND。

如果 INTERVAL 运算对象有多个字段，例如 MINUTE TO SECOND，则转换将失败，如下所示：

```
 values ( cast (INTERVAL '120' MINUTE(3) as decimal(4,2)));
+---------+
| EXPR$0  |
+---------+
+---------+
No rows selected

 values ( cast (INTERVAL '120' MINUTE(3) as decimal(4)));
+---------+
| EXPR$0  |
+---------+
| 120     |
+---------+
1 row selected

 values ( cast (INTERVAL '120' MINUTE(3) as decimal(3)));
+---------+
| EXPR$0  |
+---------+
| 120     |
+---------+
1 row selected

 values ( cast (INTERVAL '120' MINUTE(3) as decimal(2)));
+---------+
| EXPR$0  |
+---------+
+---------+
No rows selected

 values cast(interval '1.1' second(1,1) as decimal(2,1));
+---------+
| EXPR$0  |
+---------+
| 1.1     |
+---------+
1 row selected

 values cast(interval '1.1' second(1,1) as decimal(1,1));
+---------+
| EXPR$0  |
+---------+
+---------+
No rows selected
```

对于年，不允许将小数作为输入和输出。

```
values cast(interval '1.1' year (1,1) as decimal(2,1));
Error: org.eigenbase.sql.parser.SqlParseException: Encountered "," at line 1, column 35.
Was expecting:
    ")" ... (state=,code=0)
values cast(interval '1.1' year (1) as decimal(2,1));
Error: From line 1, column 13 to line 1, column 35:
              Illegal interval literal format '1.1' for INTERVAL YEAR(1) (state=,code=0)
values cast(interval '1.' year (1) as decimal(2,1));
Error: From line 1, column 13 to line 1, column 34:
              Illegal interval literal format '1.' for INTERVAL YEAR(1) (state=,code=0)
values cast(interval '1' year (1) as decimal(2,1));
+---------+
| EXPR$0  |
+---------+
| 1.0     |
+---------+
1 row selected
```

有关其他示例，请参阅“SQL 运算符：更多示例”。

## 限制
<a name="TOC11"></a>

Amazon Kinesis Data Analytics 不支持直接将数字值转换为间隔值。这偏离了 SQL:2008 标准。将数字转换为间隔的推荐方法是将数字值乘以特定的间隔值。例如，将整数 time\$1in\$1millis 转换为 day-time 间隔：

```
time_in_millis * INTERVAL '0 00:00:00.001' DAY TO SECOND
```

例如：

```
 values cast( 5000 * (INTERVAL '0 00:00:00.001' DAY TO SECOND) as varchar(11));
'EXPR$0'
'5000'
1 row selected
```