PACK 标量函数 (scalar function)

PACK函数返回一个二进制字符串值,其中包含一个数据类型数组和每个非空表达式参数的打包表示。

阅读语法图跳过可视化语法图PACK( CCSID 1208CCSID DEFAULT, ,表达式 )

该模式是 SYSIBM。

CCSID 1208
指定使用CCSID 1208对字符串值进行编码。
CCSID DEFAULT
指定字符串按原编码打包,不做CCSID转换。
表达式
返回一个值,该值将被编码到结果字符串中。 表达式必须为内置数据类型,且不能为 DECFLOAT、GRAPHIC、VARGRAPHIC、ROWID、LOB、XML 或定义为 FOR BIT DATA 的字符串。

PACK函数的结果是一个由以下项目构成的二进制字符串:

  • 为未来使用而预留的标志字节
  • 一个2字节的整数,表示结果字符串中编码的参数数量
  • 数据类型数组,其中包含一个元素,该元素包含每个编码参数的数据类型信息
  • 表达式参数的编码值,按照函数调用中指定的顺序。

生成的二进制字符串格式如下:

2字节长度 标志字节 项数 数据类型数组 编码数据值
可变长度 Varbinary 数据

数据类型数组包含每个表达式参数的元素,其顺序与函数调用中指定的顺序相同。 每个数组元素包含一个2字节的SQLTYPE值,用于指示相应表达式的数据类型。 当 SQLTYPE 值为奇数时,相应的表达式表示空值,且该值不会在结果字符串中编码。 当SQLTYPE值为偶数时,结果字符串包含根据数据类型编码的值。 下表描述了数据类型:

表 1. PACK函数的表达式数据类型
表达的数据类型 对结果字符串中编码值的描述
SMALLINT、INTEGER 或 BIGINT 根据数据类型,表达值可以是16位有符号二进制整数、32位有符号二进制整数或64位有符号二进制整数
十进制 (p,s )1 1字节精度的p、1字节精度的s(p+2)/2 字节的带符号的十进制数
2 或双 3 64位IEEE浮点格式的表达价值
CHAR 或 VARCHAR 字符串编码的2字节CCSID序列,后跟2字节字符串长度,然后是指定CCSID编码的参数数据
二进制或变长二进制 一个序列:2字节长的字符串,后跟参数数据
日期 日期的4字节无符号十进制数表示形式,格式为YYYYMMDD
时间 以HHMMSS形式表示的3字节无符号十进制数
无时区的TIMEST AMP(p ) 一个精度为p的 2字节无符号二进制整数值序列,后跟7+ (p+1)/2 字节无符号十进制打包数字表示的时间戳,格式为YYYYMMDDHHMMSSNN,其中NN为0到6字节的小数秒数,具体取决于 精度p
带时区的TIMESTAMP(p) 一个精度为p的 2字节无符号二进制整数值序列,后跟7+ (p+1)/2 字节以YYYYMMDDHHMMSSNN形式表示的时间戳无符号十进制数,其中NN为0到6字节的小数秒数,具体取决于精度p ,后跟2字节以无符号十进制数表示的时区(高阶位设置为负时区值)
备注: 小写数据类型定义如下:
  1. 十进制 = DECIMAL(p,s)NUMERIC(p,s)
  2. real = REAL 或 FLOAT(n ),其中 n 是单精度浮点数的规格
  3. double = DOUBLE、DOUBLE PRECISION、FLOAT 或 FLOAT(n ),其中 n 是双精度浮点数的规格
数据类型的同义词,无论长或短,均视为与所列的同义词相同。

所有数字数据均以大端格式表示。

函数的结果是VARBINARY。 结果的字符串长度属性为MIN(32704,即标题长度+数据类型数组长度+SUM(编码表达式值的最大长度))。结果不能为空。

示例1: 以下语句显示VARCHAR、DATE和DOUBLE值被打包成二进制字符串,然后返回给应用程序:

  SELECT PACK(CCSID 1208, 'Alina', DATE'1977-08-01', DOUBLE(0.5))
    FROM SYSIBM.SYSDUMMYU;

该语句返回一个VARBINARY字符串,内容如下(结果以十六进制格式显示,并包含空格分隔符,以便阅读。 实际结果不是十六进制格式,也不包含任何空格分隔符):

  00 0003 01C4 0180 01E0 04B80005416C696E61 19770801 3FE0000000000000

字符串“Alina”采用 UTF-8 (CCSID 1208)格式,与字符串的原始编码无关,因为PACK调用中指定了CCSID 1208。

结果字符串为VARBINARY(30)。 长度属性30由以下元素决定:

  • 1(标志字节)
  • +2(项目数量)
  • +2*3(2字节数据类型乘以项目数量)
  • +2 (CCSID) + 2 (长度) + 5 (VARCHAR(5) 数据长度)
  • +4(日期数据长度)
  • +8(双倍长度)

结果的实际长度也是30。

示例2: 以下语句表明,当将NULL值打包到二进制字符串中时,它们不会在结果的编码值部分占用任何空间:

SELECT PACK(CCSID DEFAULT, '', CAST(NULL AS TIME),
 CAST('Bridget' AS VARCHAR(20) CCSID EBCDIC))
 FROM SYSIBM.SYSDUMMYU;

该语句返回一个VARBINARY字符串,内容如下。 (结果以十六进制格式显示,并包含空格分隔符,以便阅读。 实际结果不是十六进制格式,也不包含任何空格分隔符。)

00 0003 01C4 0185 01C4 04B80000 00250007C2D9C9C4C7C5E3

字符串''(空字符串)以原始CCSID 1208格式打包,而“Bridget”则以原始CCSID 37格式打包,这是由于在PACK调用中使用了CCSID DEFAULT规范。

结果字符串为VARBINARY(40)。 40这个长度属性是由以下元素决定的:

  • 1(标志字节)
  • +2(项目数量)
  • +2*3(2字节数据类型乘以项目数量)
  • +2 (CCSID) + 2 (长度) + 0 (空字符串数据长度)
  • +3(时间数据长度)
  • +2 (CCSID) + 2 (长度) + 20 (VARCHAR(20) 最大长度)

结果字符串的实际长度为24,由以下元素决定

  • 1(标志字节)
  • +2(项目数量)
  • +2*3(2字节数据类型乘以项目数量)
  • +2 (CCSID) + 2 (长度) + 0 (空字符串数据长度)
  • +0(空)
  • +2 (CCSID) + 2 (长度) + 7 (VARCHAR(20) 实际长度)