

 从补丁 198 开始，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息，请参阅[博客文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

# CAST 函数
<a name="r_CAST_function"></a>

CAST 函数将一种数据类型转换为另一种兼容的数据类型。例如，您可以将字符串转换为日期，或将数值类型转换为字符串。CAST 执行运行时转换，这意味着转换不会更改源表中值的数据类型。仅在查询上下文中对其进行更改。

CAST 函数与 [CONVERT 函数](r_CONVERT_function.md) 非常相似，它们都将一种数据类型转换为另一种数据类型，但它们的调用方式不同。

某些数据类型需要使用 CAST 或 CONVERT 函数显式转换为其他数据类型。其他数据类型可进行隐式转换（作为另一个命令的一部分），无需使用 CAST 或 CONVERT。请参阅[类型兼容性和转换](c_Supported_data_types.md#r_Type_conversion)。

## 语法
<a name="r_CAST_function-syntax"></a>

使用以下两个等效的语法形式，将表达式从一种数据类型强制转换为另一种数据类型。

```
CAST ( expression AS type )
expression :: type
```

## 参数
<a name="r_CAST_function-arguments"></a>

 *expression*   
计算结果为一个或多个值的表达式，如列名称或文本。转换 null 值将返回 null。表达式不能包含空白或空字符串。

 *type*   
支持的 [数据类型](c_Supported_data_types.md) 之一。

## 返回类型
<a name="r_CAST_function-return-type"></a>

CAST 返回 *type* 参数指定的数据类型。

**注意**  
如果您尝试执行有问题的转换（例如，会导致精度损失的 DECIMAL 转换），Amazon Redshift 将返回错误。有问题的转换示例如下：  

```
select 123.456::decimal(2,1);
```
或导致溢出的 INTEGER 转换：  

```
select 12345678::smallint;
```

## 示例
<a name="r_CAST_function-examples"></a>

某些示例使用示例 [TICKIT 数据库](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html)。有关设置示例数据的更多信息，请参阅[加载数据](https://docs.aws.amazon.com/redshift/latest/gsg/cm-dev-t-load-sample-data.html)。

以下两个查询是等效的。它们都将小数值转换为整数：

```
select cast(pricepaid as integer)
from sales where salesid=100;

pricepaid
-----------
162
(1 row)
```

```
select pricepaid::integer
from sales where salesid=100;

pricepaid
-----------
162
(1 row)
```

以下内容会产生类似的结果。它不需要示例数据即可运行：

```
select cast(162.00 as integer) as pricepaid;

pricepaid
-----------
162
(1 row)
```

在此示例中，时间戳列中的值将强制转换为日期，这会导致从每个结果中删除时间：

```
select cast(saletime as date), salesid
from sales order by salesid limit 10;

 saletime  | salesid
-----------+---------
2008-02-18 |       1
2008-06-06 |       2
2008-06-06 |       3
2008-06-09 |       4
2008-08-31 |       5
2008-07-16 |       6
2008-06-26 |       7
2008-07-10 |       8
2008-07-22 |       9
2008-08-06 |      10
(10 rows)
```

如果您没有像前一个示例中所示的那样使用 CAST，则结果将包括时间：*2008-02-18 02:36:48*。

以下查询将可变字符数据强制转换为日期。它不需要示例数据即可运行。

```
select cast('2008-02-18 02:36:48' as date) as mysaletime;

mysaletime    
--------------------
2008-02-18  
(1 row)
```

在此示例中，日期列中的值将强制转换为时间戳：

```
select cast(caldate as timestamp), dateid
from date order by dateid limit 10;

      caldate       | dateid
--------------------+--------
2008-01-01 00:00:00 |   1827
2008-01-02 00:00:00 |   1828
2008-01-03 00:00:00 |   1829
2008-01-04 00:00:00 |   1830
2008-01-05 00:00:00 |   1831
2008-01-06 00:00:00 |   1832
2008-01-07 00:00:00 |   1833
2008-01-08 00:00:00 |   1834
2008-01-09 00:00:00 |   1835
2008-01-10 00:00:00 |   1836
(10 rows)
```

在与前面的示例类似的情况下，您可以使用 [TO\$1CHAR](https://docs.aws.amazon.com/redshift/latest/dg/r_TO_CHAR.html) 进一步控制输出格式。

在此示例中，整数将强制转换为字符串：

```
select cast(2008 as char(4));

bpchar
--------
2008
```

在此示例中，DECIMAL(6,3) 值将强制转换为 DECIMAL(4,1) 值：

```
select cast(109.652 as decimal(4,1));

numeric
---------
109.7
```

此示例显示了一个更复杂的表达式。SALES 表中的 PRICEPAID 列（DECIMAL(8,2) 列）将转换为 DECIMAL(38,2) 列，并且值将乘以 100000000000000000000：

```
select salesid, pricepaid::decimal(38,2)*100000000000000000000
as value from sales where salesid<10 order by salesid;


 salesid |           value
---------+----------------------------
       1 | 72800000000000000000000.00
       2 |  7600000000000000000000.00
       3 | 35000000000000000000000.00
       4 | 17500000000000000000000.00
       5 | 15400000000000000000000.00
       6 | 39400000000000000000000.00
       7 | 78800000000000000000000.00
       8 | 19700000000000000000000.00
       9 | 59100000000000000000000.00
(9 rows)
```

**注意**  
无法对 `GEOMETRY` 数据类型执行 CAST 或 CONVERT 操作来将其更改为其他数据类型。不过，您可以提供扩展的已知二进制 (EWKB) 格式的字符串文字的十六进制表示形式，作为接受 `GEOMETRY` 参数的函数的输入。例如，下面的 `ST_AsText` 函数需要 `GEOMETRY` 数据类型。  

```
SELECT ST_AsText('01010000000000000000001C400000000000002040');
```

```
st_astext  
------------
 POINT(7 8)
```
您也可以明确指定 `GEOMETRY` 数据类型。  

```
SELECT ST_AsText('010100000000000000000014400000000000001840'::geometry);
```

```
st_astext  
------------
 POINT(5 6)
```