GBase 8s SQL 指南:教程———5在SELECT语句中使用函数

5在SELECT语句中使用函数

除了列名和运算符之外,表达式还可包括一个或多个函数。本章说明如何在SELECT语句 中使用函数来执行更复杂的数据库查询和数据处理。

有关下列SQL函数以及其它SQL函数的语法的信息,请参阅《GBase 8s SQL指南:语 法》中表达式段。

提示: 还可以使用您自己创建的函数。有关用户定义函数的信息,请参阅创建和使用SPL例 程和《GBase 8s用户定义的例程和数据类型开发者指南》。

5.1在SELECT语句中使用函数

可以在选择列表中使用任何基本类型的表达式(列、常量、函数、聚集函数和过程)或它 们的组合。

函数表达式使用对查询中的每一行进行求值的函数。所有函数表达式都需要参数。当在列 名用作参数的情况下使用这一组表达式时,这些表达式包含时间函数和长度函数。

5.1.1聚集函数

聚集函数对一组查询返回一个值。聚集函数取用依赖于SELECT语句的WHERE子句返 回的一组行的值。没有WHERE子句时,聚集函数取用依赖于FROM子句组成的所有行 的值。

不能将聚集函数用于包含下列数据类型的表达式中:

TEXT
BYTE
CLOB
BLOB
集合数据类型(LIST、MULTISET和SET)
ROW 类型
•不透明数据类型(支持不透明数据类型的用户定义的聚集函数除外)

聚集通常用于总结有关表中的行组的信息。此用法在编写高级SELECT语句中讨论。当将 聚集函数应用于整个表时,结果将包含总结所有选择的行的一行。

所有的GBase 8s数据库服务器都支持下列聚集函数。

AVG函数

下列查询计算stock表中所有行的平均值unit_price。

图:查询

SELECT AVG (unit_price) FROM stock;

图:查询结果

(avg)

$197.14

下列查询只计算stock表中manu_code为SHM的那些行的平均值unit_price。

图:查询

SELECT AVG (unit_price) FROM stock WHERE manu_code = ‘SHM’;

图:查询结果

(avg)

$204.93

COUNT函数

下列查询对stock表中的总行数进行计数和显示。

图:查询

SELECT COUNT(*) FROM stock;

图:查询结果

(count(*))

73

下列查询包含WHERE子句来对stock表中的特定行(在此示例中, 是manu_code为SHM的那些行)进行计数。

图:查询

SELECT COUNT (*) FROM stock WHERE manu_code = ‘SHM’;

图:查询结果

(count(*))

17

通过包含DISTINCT关键字(或它的同义词UNIQUE)和列名,可以计算stock表中不同 制造商代码的数目。

图:查询

SELECT COUNT (DISTINCT manu_code) FROM stock;

图:查询结果

(count)

9

MAX和MIN函数

可以在同一 SELECT语句中组合聚集函数。例如,可以同时在选择列表中包

括MAX和MIN函数。如下所示。

图:查询

SELECT MAX (ship_charge), MIN (ship_charge) FROM orders;

该查询查找并显示orders表中的最大和最小ship_charge。

图:查询结果

(max) (min)

$25.20 $5.00

RANGE函数

RANGE函数计算所选行的最大值与最小值之差。

只能将RANGE函数应用于数字列。下列查询查找stock表中商品的价格范围。

图:查询

SELECT RANGE(unit_price) FROM stock;

图:查询结果

(range)

955.50

对于其它聚集函数,当查询包括GROUP BY子句时,RANGE函数适用于组的行,如下所 示。

图:查询

SELECT RANGE(unit_price) FROM stock

GROUP BY manu_code;

图:查询结果

(range)

820.20

595.50

720.00

225.00

632.50

0.00

460.00

645.90

425.00

STDEV函数

STDEV函数计算所选行的标准偏差。它是VARIANCE函数的平方根。.

可将STDEV函数应用于数字列。下列查找入口的标准偏差:

SELECT STDEV(age) FROM u_pop WHERE age > 21;

对于其它聚集,当查询包括GROUP BY子句时,STDEV函数适用于组的行。如下所示:

SELECT STDEV(age) FROM u_pop

GROUP BY state

WHERE STDEV(age) > 21;

除非指定列中的每个值都是空值,否则会忽略空值。如果每个列值都是空值,那么STDEV函 数对该列返回空值。有关STDEV函数的更多信息,请参阅《GBase 8s SQL指南:语法》 中的表达式段。

SUM函数

下列查询计算1998年7月13日交付的所有订单的总ship_weight。

图查询

SELECT SUM (ship_weight) FROM orders

WHERE ship_date = ‘07/13/1998’;

图: 查询结果

(sum)

130.5

VARIANCE 函数

VARIANCE函数返回值样本的方差作为所有选择行的方差的无偏估计。它计算以下值:

(SUM(Xi**2) - (SUM(Xi)**2)/N)/(N-1)

在此示例中,Xi是列中的每个值,N是列中值的总数。只能将VARIANCE函数应用于数 字列。以下查询查找入口的标准偏差:

SELECT VARIANCE(age) FROM u_pop WHERE age > 21;

对于其它聚集,当查询包括GROUP BY子句时,VARIANCE函数适用于组的行。如下所 示:

SELECT VARIANCE(age) FROM u_pop

GROUP BY birth

WHERE VARIANCE(age) > 21;

除非指定列中的每个值都是空值,否则会忽略空值。如果每个列值都是空值,那

么VARIANCE函数对该列返回空值。有关VARIANCE函数的更多信息,请参阅《GBase 8s SQL指南:语法》中的表达式段。

将函数应用于表达式

下列查询显示如何将函数应用于算术表达式并为其结果提供显示标签:

图:查询

SELECT MAX (res_dtime - call_dtime) maximum,

MIN (res_dtime - call_dtime) minimum, AVG (res_dtime - call_dtime) average FROM cust_calls;

该查询查找和显示收到和处理客户来电之间的最长、最短和平均时间(以日、小时和分钟 计)并相应地标记派生值。该查询结果显示这些时间量。

图:查询结果

maximum minimum average

5 20:55 0 00:01 1 02:56

5.1.2时间函数

可以在查询的Projection子句或 WHERE子句中使用时间函数DAY、MONTH、

WEEKDAY和YEAR。这些函数返回与用来调用函数的表达式或参数对应的值。还可以使 用CURRENT或SYSDATE函数返回具有当前日期和时间的值,或者使用EXTEND函数调 整 DATE 或 DATETIME 值。

DAY 和 CURRENT 函数

下列查询在两个expression列中对call_dtime和res_dtime列返回日期(一个月中的某一 天)。

图:查询

SELECT customer_num, DAY (call_dtime), DAY (res_dtime) FROM cust_calls;

图:查询结果

customer_num (expression) (expression)

106

12

12

110

7

7

119

1

2

121

10

10

127

31

116

28

28

116

21

27

下列查询使用DAY和CURRENT函数来将列值与当前日期(月中某日)进行比较。它只 选择值比当前日期早的那些行。在此示例中,CURRENT日是15。

图:查询

SELECT customer_num, DAY (call_dtime), DAY (res_dtime)

FROM cust_calls

WHERE DAY (call_dtime) < DAY (CURRENT);

图:查询结果

customejnum (expression) (expression)

106

12

12

110

7

7

119

1

2

121

10

10

下列查询使用CURRENT函数来选择除今天打的电话之外的所有来电。

图:查询

SELECT customer_num, call_code, call_descr

FROM cust_calls

WHERE call_dtime < CURRENT YEAR TO DAY;

图:查询结果

customer_num 106

call_code D

call_descr Order was received, but two of the cans of ANZ tennis balls

within the case were empty

customer_num 110

call_code L

call_descr Order placed one month ago (6/7) not received.

customer_num 116

call_code I

call_descr Second complaint from this customer! Received two cases right-handed outfielder gloves (1 HRO) instead of one case lefties.

SYSDATE函数与CURRENT函数及其类似,但当未指定DATETIME限定符时,其返回 值的缺省精度是DATETIME YEAR TO FRACTION。),而不是CURRENT的缺省精度 DATETIME YEAR TO FRACTION^)。

MONTH函数

下列查询使用MONTH函数来抽取和显示在哪个月份接收和处理客户来电,并且它将对结 果列使用显式标签。但是,它不区分年份。

图查询

SELECT customer_num,

MONTH (call_dtime) call_month,

MONTH (res_dtime) res_month

FROM cust_calls;

图: 查询结果

customer_num call_month res_month

106 6 6

110 7 7

119

7

7

121

7

7

127

7

116

11

11

116

12

12

如果DAY比当前日期早,那么下列查询使用MONTH函数和DAY及CURRENT来显示在 哪个月份接收和处理客户来电。

图:查询

SELECT customer_num,

MONTH (call_dtime) called,

MONTH (res_dtime) resolved FROM cust_calls

WHERE DAY (res_dtime) < DAY (CURRENT);

图:查询结果

customer_num called

resolved

106

6

6

119

7

7

121

7

7

WEEKDAY 函数

下列查询使用WEEKDAY函数来指示在星期几接收并处理来电(0表示星期日,1表示星 期一,以此类推),并标记表达式列。

图:查询

SELECT customer_num,

WEEKDAY (call_dtime) called,

WEEKDAY (res_dtime) resolved

FROM cust_calls ORDER BY resolved;

图:查询结果

customer_num called resolved

127

3

110

0

0

119

1

2

121

3

3

116

3

3

106

3

3

116

5

4

下列查询使用COUNT和WEEKDAY函数来对在周末收到的来电进行计数。此类语句能够 使您了解客户来电模式或指示是否需要加班费。

图:查询

SELECT COUNT(*)

FROM cust_calls WHERE WEEKDAY (call_dtime) IN (0,6);

图:查询结果

(count(*))

4

YEAR函数

下列查询检索call_dtim e比当前年份的开始早的行。

图:程序

SELECT customer_num, call_code,

YEAR (call_dtime) call_year,

YEAR (res_dtime) res_year

FROM cust_calls

WHERE YEAR (call_dtime) < YEAR (TODAY);

图:查询结果

customejnum call_code call_year res_year

116 I 1997 1997

116 I 1997 1997

格式化DATETIME值

在下列查询中,EXTEND函数仅显示指定的子字段以限制两个DATETIME值。

图:程序

SELECT customejnum,

EXTEND (call_dtime, month to minute) call_time,

EXTEND (res_dtime, month to minute) res_time

FROM cust_calls

ORDER BY res_time;

该查询为标签为call_time和res_time的列返回月份至分钟范围,提供工作量的指示。

图:查询结果

customer num call time res time

127 07-31 14:30

106 06-12 08:20 06-12 08:25

119 07-01 15:00 07-02 08:21

110 07-07 10:24 07-07 10:30

121 07-10 14:05 07-10 14:06

116 11-28 13:34 11-28 16:47

116 12-21 11:24 12-27 08:19

TO_CHAR函数也可以格式化DATETIME值。有关内置函数的信息,请参阅TO_CHAR 函数,该函数也可接受作为参数的DATE值或数字值并返回格式化的字符串。

除了这些示例说明的内置时间函数之外,GBase 8s还支持ADD_MONTHS、LAST_DAY、 MDY、MONTHS_BETWEEN、NEXT_DAY 和QUARTER 函数。除了这些函数,

TRUNC和ROUND函数也可返回更改DATE或DATETIME参数精度的值。这些附加时 间函数在GBase 8s SQL指南:语法中进行了描述。

5.1.3数据转换函数

可以在使用表达式的任何地方使用数据转换函数。

下列转换函数在日期与字符串之间转换:

DATE函数

DATE函数将字符串转换为DATE值。在以下查询中,DATE函数将字符串转换为DATE 值,以允许与DATETIME值进行比较。仅当call_dtime值比指定的DATE晚时查询才会检 索 DATETIME 值。

图:查询

SELECT customer_num, call_dtime, res_dtime

FROM cust_calls

WHERE call_dtime > DATE (‘12/31/97’);

图: 查询结果

customer_num call_dtime res_dtime

106 1998-06-12 08:20 1998-06-12 08:25

110 1998-07-07 10:24 1998-07-07 10:30

119 1998-07-01 15:00 1998-07-02 08:21

121 1998-07-10 14:05 1998-07-10 14:06

127 1998-07-31 14:30

仅当call_dtime大于或等于指定日期时,下列查询才会将DATETIME值转换为DATE格 式并带标签显示这些值。

图查询

SELECT customer_num,

DATE (call_dtime) called,

DATE (res_dtime) resolved

FROM cust_calls

WHERE call_dtime >= DATE (‘1/1/98’);

图:查询结果

customer_num called resolved

106 06/12/1998

06/12/1998

110 07/07/1998

07/07/1998

119 07/01/1998

07/02/1998

121 07/10/1998

07/10/1998

127 07/31/1998

TO_CHAR 函数

TO_CHAR函数将DATETIME或DATE值转换为字符串值。TO_CHAR函数根据您指定 的日期格式化伪指令对DATETIME值进行求值并返回NVARCHAR值。有关受支持的日 期格式化伪指令的列表,请参阅《GBase 8s GLS用户指南》GL_DATETIME环境变量的 描述。

还可以使用TO_CHAR函数将DATETIME或DATE值转换为LVARCHAR值。

下列查询使用TO_CHAR函数将DATETIME值转换为可读性更强的字符串。

图:查询

SELECT customer_num,

TO_CHAR(call_dtime, “%A %B %d %Y”) call_date

FROM cust_calls

WHERE call_code = “B”;

图:查询结果

customer_num 119

call_date Friday July 01 1998

下列查询使用TO_CHAR函数将DATE值转换为可读性更强的字符串。

图查询

SELECT order_num,

TO_CHAR(ship_date,"%A %B %d %Y") date_shipped

FROM orders

WHERE paid_date IS NULL;

图:查询结果

order_num 1004

date_shipped

Monday May 30 1998

order_num

1006

date_shipped

order_num

1007

date_shipped

Sunday June 05 1998

order_num

1012

date_shipped

Wednesday June 29 1998

order_num

1016

date_shipped

Tuesday July 12 1998

order_num

1017

date_shipped

Wednesday July 13 1998

TO_CHAR函数还可以格式化数字值。有关内置TO_CHAR函数的更多信息,请参阅《GBase 8s SQL指南:语法》。

TO_DATE 函数

TO_DATE函数接受字符数据类型的参数并将此值转换为DATETIME值。TO_DATE函数 根据您指定的日期格式化伪指令对字符串求值并返回DATETIME值。有关受支持的日期 格式化伪指令的列表,请参阅《GBase 8s GLS用户指南》中GL_DATETIME环境变量的 描述。

还可以使用TO_DATE函数将LVARCHAR值转换为DATETIME值。

下列查询使用TO_DATE函数将字符串转换为指定格式的DATETIME值。

图:查询

SELECT customer_num, call_descr

FROM cust_calls

WHERE call_dtime = TO_DATE(“2OO8-O7-O7 10:24”,

“%Y-%m-%d %H:%M”);

图:查询结果

customer_num 110

call_descr Order placed one month ago (6/7) not received.

可以使用DATE或TO_DATE函数来将字符串转换为DATE值。TO_DATE函数的一个优 点是它允许您为返回的值指定格式。(可以使用TO_DATE函数(它总是返回DATETIME 值)来将字符串转换为DATE值,原因是数据库月服务器隐式处理DATE和DATETIME 值之间的转换。)

5.1.4基数函数

CARDINALITY函数对集合包含的元素数目计数。可以将CARDINALITY函数与简单或嵌 套集合配合使用。将集合中的任何重复作为个别元素计数。下列查询显示一个查询,它 对manager表中的每一列返回department值和每个direct_reports集合中的元素数。

图:查询

SELECT department, CARDINALITY(direct_reports) FROM manager;

图:查询结果

department marketing 5

department engineering 7

department publications 4

department accounting 3

还可以从谓词表达式中对集合的元素数进行求值,如下所示。

SELECT department, CARDINALITY(direct_reports) FROM manager

WHERE CARDINALITY(direct_reports) < 6

GROUP BY department;

图:查询结果

department accounting 3

department marketing 5

department publications 4

5.1.5智能大对象函数

数据库服务器提供了四个SQL函数,您可以从SQL语句中调用这些函数来导入和导出智 能大对象。下表显示智能大对象函数。

表1.智能大对象的SQL函数

函数名称

用途

FILETOBLOB()

将文件复制到BLOB列中

FILETOCLOB()

将文件复制到CLOB列中

LOCOPY()

将BLOB或CLOB数据复制的另一个BLOB或CLOB列中

LOTOFILE()

将BLOB或CLOB数据复制到文件中

有关智能大对象函数的详细信息和语法,请参阅《GBase 8s SQL指南:语法》中的表达式 段。

可以在SELECT UPDATE和INSERT语句中使用该表显示的任何函数。有关如何在 INSERT和UPDATE语句中使用上述函数的示例,请参阅修改数据。

假设您创建inmate和fbi_list表,如下图所示。

图:仓建inmate和fbijist表

CREATE TABLE inmate

(

id_num INT,

picture BLOB,

felony CLOB

);

CREATE TABLE fbi_list

(

id INTEGER,

mugshot BLOB

)PUT mugshot IN (sbspacel);

以下SELECT语句使用LOTOFILE()函数将数据从felony列复制到位于客户机上 的 felon_322.txt 文件中:

SELECT id_num, LOTOFILE(felony, ‘felon_322.txt’, ‘client’)

FROM inmate

WHERE id = 322;

LOTOFILE()的第一个参数指定将从中导岀数据的列的名称。第二个参数指定要将数据复制 到其中的文件的名称。第三个参数指定目标文件是位于客户端计算机(‘client’)或服务器计 算机(‘server’)上。

根据源文件是驻留在客户机还是服务器计算机上,下列规则可用来指定函数参数中文件名 的路径:

如果源文件驻留在服务器计算机上,那么必须指定文件的全路径名(不是与当前工作目录 相对的路径名)。

如果源文件驻留在客户端计算机上,那么可以指定文件的全路径名或相对路径名。

5.1.6字符串处理函数

字符串处理函数接受类型为CHAR、NCHAR、VARCHAR、NVARCHAR或 LVARCHAR的参数。可以在使用表达式的任何地方使用字符串处理函数。

下列函数在字符串中进行大写字母和小写字母之间的转换:

LOWER
UPPER
INITCAP
下列函数以各种方法处理字符串:

REPLACE
SUBSTR
SUBSTRING
LPAD
RPAD
限制:不能过载任何字符串处理函数来处理扩展数据类型。

LOWER函数

使用LOWER函数来将字符串中的每个大写字母替换为小写字母。LOWER函数接受字符 数据类型的参数并返回具有与指定的参数相同数据类型的值。

下列函数使用LOWER函数来将字符串的任何大写字母转换为小写字母。

图:查询

SELECT manu_code, LOWER(manu_code)

FROM items

WHERE order_num = 1018

图:查询结果

manu_code (expression)

PRC

prc

KAR

kar

PRC

prc

SMT

smt

HRO

hro

UPPER函数

使用UPPER函数来将字符串中的每个小写字母替换为大写字母。UPPER函数接受字符数 据类型的参数并返回具有与指定的参数相同数据类型的值。

下列查询中UPPER函数将字符串中的任何小写字母转换为大写字母。

图:查询

SELECT call_code, UPPER(code_descr) FROM call_type

图:查询结果

call_code (expression)

B BILLING ERROR

D DAMAGED GOODS

I INCORRECT MERCHANDISE SENT

L LATE SHIPMENT

O OTHER

INITCAP 函数 使用INITCAP函数来将字符串中每个词的首字母替换为大写字母。每当函数遇到字母之前 是非字母字符时,INITCAP函数就会假设是一个新词。INITCAP函数接受字符数据类型的 参数并返回指定参数相同数据类型的值。

下列查询使用INITCAP函数将字符串中每个词的首字母替换为大写字母。

图查询

SELECT INITCAP(description) FROM stock

WHERE manu_code = “ANZ”;

图:查询结果

(expression)

Tennis Racquet

Tennis Ball

Volleyball

Volleyball Net

Helmet

Golf Shoes

3 Golf Balls

Running Shoes

Watch

Kick Board

Swim Cap

REPLACE 函数

使用REPLACE函数来将字符串中的某一组字符替换为其它字符。

在以下查询中,REPLACE函数将单元列值each替换为查询返回的每一行的item。

REPLACE函数的第一个参数是要进行求值的表达式。第二个参数指定想要替换的字符。第 三个参数指定要替换除去的字符的新字符串。

图查询

SELECT stock_num, REPLACE(unit,"ench”, “item”) cost_per, unit_price

FROM stock

WHERE manu_code = “HRO”;

图: 查询结果

stock_num cost_per unit_price

1

case

$250.00

2

case

$126.00

4

case

$480.00

7

case

$600.00

110

case

$260.00

205

case

$312.00

301

item

$42.50

302

item

$4.50

304

box

$280.00

305

case

$48.00

309

case

$40.00

312

box

$72.00

SUBSTRING 和 SUBSTR 函数

可以使用SUBSTRING和SUBSTR函数返回部分字符串。指定开始位置和长度(可选)来 确定函数返回字符串的哪部分。

限制: 这两个函数在参数中的使用测量单位是字节,而非逻辑字符。这在缺省语言环境和另 一个单字节语言环境中都不重要,但是您不能在代码集与其存储长度不同的逻辑字符的语言环 境中调用 SUBSTRING 或 SUBSTR。

SUBSTRING 函数

可以使用SUBSTRING函数来返回字符串的某部分。指定开始位置和长度(可选)来确定 返回字符串的哪部分。可以指定正数或负数作为开始位置。开始位置1指定SUBSTRING函 数从字符串的第一个位置开始。当开始位置为(0)或负数时,SUBSTRING函数从字符串 的开头开始向后计数。

下列查询显示SUBSTRING函数的一个示例,其返还查询返回的任何sname列值的前四个 字符。在本示例中,SUBSTRING函数从字符串的开头开始,返回开始位置开始的四个字 符。

图:查询

SELECT sname, SUBSTRING(sname FROM 1 FOR 4) FROM state

WHERE code = “AZ”;

图:查询结果

sname (expression)

Arizona Ariz

在下列查询中,SUBSTRING函数指定开始位置6,但未指定长度。函数返回从字符串的第 六个位置开始到字符串结尾的字符串。

图:查询

SELECT sname, SUBSTRING(sname FROM 6) FROM state

WHERE code = “WV”;

图:查询结果

sname (expression)

West Virginia Virginia

在下列查询中,SUBSTRING函数只返回查询返回的任何sname列值的第一个字符。对 于SUBSTRING函数,开始位置-2表示从字符的开始位置向后数三个位置(0、-1、-2) (对于开始位置0,函数从字符串的开始位置向后数一个位置)。

图:查询

SELECT sname, SUBSTRING(sname FROM -2 FOR 4) FROM state

WHERE code = “AZ”;

图:查询结果

sname (expression)

Arizona A

SUBSTR函数

SUBSTR函数的作用于SUBSTRING函数相同,但两个函数的语法有区别。

要返回字符串的一部分,指定开始位置和长度(可选)来确定SUBSTR函数返回子串的哪 个部分。为SUBSTR函数指定的开始位置可以是正数,也可以是负数。然而,SUBSTR函 数用与SUBSTRING函数不同的方式处理开始位置中的负数。当开始位置是负数时, SUBSTR函数从字符串的末尾开始向后计数,这取决于字符串的长度,而不是字符串包含 词或可视字符的长度。SUBSTR函数将开始位置中的零(0)或1识别为字符串中的第一个 位置。

下列查询显示包括负数作为开始位置的SUBSTR函数的一个示例。假定开始位置为-15, 那么SUBSTR函数从字符串末尾开始向后数15个位置来找到开始位置,然后返回下五个 字符。

图:查询

SELECT sname, SUBSTR(sname, -15, 5) FROM state

WHERE code = “CA”;

图:查询结果

sname (expression)

California Calif

要使用负数作为开始位置,需要指定求出的长度值。sname列被定义为CHAR(15),因此接 受类型为sname的参数的SUBSTR函数可以将开始位置0、1或-15用于函数来返回从字 符串的第一个位置开始的字符串。

下列查询返回与图1相同的结果。

图:查询

SELECT sname, SUBSTR(sname, 1,5) FROM state

WHERE code = “CA”;

LPAD函数

使用LPAD函数返回已用重复次数达到必要次数的字符序列在左边填充或截断的字符串的 副本,这取决于字符串中填充部分的指定长度。指定源字符串、要返回的字符串的长度和 要用来填充的字符串。

源字符串和用来填充的字符串的数据类型可以是能转换为VARCHAR或NVARCHAR 的任何数据类型。

下列查询显示具有指定长度21个字节的LPAD函数的一个示例。由于源字符串长度为15 个字节(sname被定义为CHAR(15)),所以LPAD函数填充字符串左边的前六个位置。

图:查询

SELECT sname, LPAD(sname, 21,"-")

FROM state

WHERE code = “CA” OR code = “AZ”;

图:查询结果

sname (expression)

California California

Arizona Arizona

RPAD函数

所以RPAD函数返回已用重复次数达到必要次数的字符序列在右边填充或截断的字符串的 副本,这取决于字符串中填充部分的指定长度。指定源字符串、要返回的字符串的长度和 要用来填充的字符串。

源字符串和用来填充的字符串的数据类型可以是能转换为VARCHAR或NVARCHAR 的任何数据类型。

下列查询显示具有指定长度21个字节的RPAD函数的一个示例。由于源字符串长度为15 个字节(sname被定义为CHAR(15)),所以LPAD函数填充字符串右边的前六个位置。

图:查询

SELECT sname, RPAD(sname, 21,

FROM state

WHERE code = “WV” OR code = “AZ”;

图:查询结果

sname (expression)

West Virginia West Virginia

Arizona Arizona

除了这些函数之外,LTRIM和RTRIM函数可以返回删除其字符串参数中指定前导或尾随 填充字符的值,并且ASCII函数可以返回在其字符串参数中第一个字符的ASCII字符集 中代码点的数字值。这些内置函数对字符串值的操作在GBase 8s SQL指南:语法中进行了 描述。

5.1.7其它函数

还可以在使用常量的SQL表达式中的任意位置使用LENGTH、USER、CURRENT , SYSDATE和TODAY函数。另外,可以在SELECT语句中包括DBSERVERNAME函数 来显示当前数据库所驻留的数据库服务器的名称。

还可以使用这些函数来选择全部由常量值组成的表达式或包括列数据的表达式。在一个实 例中,对于所有输出行,结果相同。

另外,可以使用HEX函数返回表达式的十六进制编码,使用ROUND函数来返回表达式的 四舍五入值,使用TRUNC函数来返回表达式的截断值。有关上述函数的更多信息,请参 阅《GBase 8s SQL指南:语法》。

LENGTH函数

在下列查询中,LENGTH函数针对company的长度大于15的每个行计算组 合fname和lname列的字节数。

图:查询

SELECT customer_num,

LENGTH (fname) + LENGTH (lname) namelength

FROM customer

SBASe"

GBase 8s SQL指南:教程

WHERE LENGTH (company) > 15;

图:查询结果

customejnum

namelength

101

11

105

13

107

11

112

14

115

11

118

10

119

10

120

10

122

12

124

11

125

10

126

12

127

10

128

11

尽管LENGTH函数在使用DB-Access时可能不是非常有用,但用于确定程序和报告的长度 时它就非常重要。LENGTH函数返回CHARACTER或VARCHAR字符串的剪切长度以 及TEXT或BYTE字符串中的全部字节数。

GBase 8s还支持CHAR_LENGTH函数,该函数在其字符串参数中返回逻辑字符数而不是 返回字节数。该函数在单个逻辑字符可能需要多个单字节存储的语言环境中非常有用。有 关CHAR_LENGTH函数的更多信息,请参阅《GBase 8s SQL指南:语法》和《GBase 8s GLS 用户指南》。

USER函数

当想要定义仅包含包括您的用户标识行的表的受限视图时,使用USER函数。有关如何创 建视图的信息,请参阅《GBase 8s SQL指南:语法》中的GRANT和CREATE VIEW 语 句。

下列查询返回执行查询的用户的用户名(登录用户名),对表中的每行重复一次。

图:查询

SELECT * FROM cust_calls

WHERE user_id = USER;

如果当前用户的用户名是richc,该查询仅检索cust_calls表中user_id = richc的行。

图:查询结果

customejnum 110

call_dtime

1998-07-07 10:24

user_id

richc

call_code

L

call_descr

Order placed one month ago (6/7) not received.

res_dtime

1998-07-07 10:30

res_descr

Checked with shipping (Ed Smith). Order sent yesterday-we

were waiting for goods from ANZ. Next time will call with

delay if necessary

customer_num 119

call_dtime 1998-07-01 15:00

user_id richc

call_code B

call_descr Bill does not reflect credit from previous order

res_dtime 1998-07-02 08:21

res_descr Spoke with Jane Akant in Finance. She found the error and

is

sending new bill to customer

TODAY函数

TODAY函数返回当前系统日期。如果下列查询是在当前系统日期为1998年7月10日 时发出的,它返回这一行。

图查询

SELECT * FROM orders WHERE order_date = TODAY;

图:查询结果

order_num 1018

order_date

07/10/1998

customer_num

i 121

ship_instruct

SW corner of Biltmore Mall

backlog

n

po_num

S22942

ship_date

07/13/1998

ship_weight

70.50

ship_charge $20.00

paid_date 08/06/1998

DBSERVERNAME 和 SITENAME 函数

可以在SELECT语句中包含DBSERVERNAME (或它的同义词SITENAME)函数来查询 数据库服务器的名称。可以查询DBSERVERNAME以找到具有行的任何表,包括系统目录 表。

在下列查询中,将标签server指定给DBSERVERNAME表达式并且也从systables系统目录 表中选择tabid列。此表描述数据库表,tabid就是表标识。

图:查询

SELECT DBSERVERNAME server, tabid

FROM systables

WHERE tabid <= 4;

图:查询结果

server

tabid

montague

1

montague

2

montague

3

montague

4

WHERE子句限制显示的行数。否则,可能会对systables表的每一行显示数据库服务器名 一次。

HEX函数

在下列查询中,HEX函数返回customer中两列的十六进制格式,如下所示。

图:查询

SELECT HEX (customer_num) hexnum, HEX (zipcode) hexzip

FROM customer;

图:查询结果

hexnum hexzip

0x00000065 0x00016F86

0x00000066 0x00016FA5

0x00000067 0x0001705F

0x00000068 0x00016F4A

0x00000069 0x00016F46

0x0000006A 0x00016F6F

DBINFO函数

可以在SELECT与中调用DBINFO函数来查询下列任何信息:

与tblspace号或表达式对应的dbspace的名称
表中插入的最后一个SERIAL、SERIAL8或BIGSERIAL值
SELECT、INSERT、DELETE、UPDATE、MERGE、EXECUTE FUNCTION、 EXECUTE PROCEDURE 或 EXECUTE ROUTINE 语句处理的行数
•当前会话的会话ID

•会话连接的当前的数据库的名称

INSERT、UPDATE或DELETE语句是否作为应答事务一部分正在执行
•数据库服务器在其上运行的主计算机的名称

•操作系统的类型和主计算机的名称

全球标准时间(UTC )格式的本地时区和当前日期和时间
对应于指定的整型列或指定的UTC时间值的DATETIME值(作为自1970-01-01 00:00:00+00:00 的秒数)
•客户机应用程序连接至的数据库服务器的精确版本或指定完整版本字符串的组件 可以在SQL语句中和SPL例程中的任何地方使用DBINFO函数。

下列查询显示可以和如何使用DBINFO函数来找出数据库服务器在其上运行的主计算机的 名称。

图:查询

SELECT FIRST 1 DBINFO(‘dbhostname’) FROM systables;

图:查询结果

(constant)

lyceum

没有FIRST 1子句来限制tabid中的值,将对systables表的每一行重复数据库服务器在其上 运行的计算机的主机名。下列查询显示可以如何使用DBINFO函数来找出当前数据库服务 器的完整版号和类型。

图查询

SELECT FIRST 1 DBINFO(‘version’,‘full’) FROM systables;

有关如何使用DBINFO函数查找您当前数据库服务器、数据库会话或数据库的信息的更多 信息,请参阅《GBase 8s SQL指南:语法》。

DECODE函数

可以使用DECODE函数来将具有一个值的表达式转换为另一个值。DECODE函数具有以 下格式:

DECODE(test, a, a_value, b, b_value, …, n, n_value, exp_m )

在通常情况下,当a等于test时DECODE函数返回a_value,当b等于test时,返回b_value, 当n等于test时返回n_value。

如果有若干表达式与test匹配,那么DECODE返回找到的第一个表达式的n_value。如果 没有表达式与test匹配,那么DECODE返回exp_m;;如果没有表达式与test匹配并且不存 在 exp_m,那么 DECODE 返回 NULL。

限制:DECODE函数不支持类型为TEXT或BYTE的参数。

假设包括emp_id和evaluation列的employee表存在。此外还假设对employee表执行下列 查询则返回以下所示的行。

图查询

SELECT emp_id, evaluation FROM employee;

图:查询结果

emp_id evaluation

012233 great

012344 poor

012677 NULL

012288 good

012555 very good

在某些情况下,您可能想要转换一组值。例如:假设您想要将前一示例中evaluation列的描 述值转换为相应的数字值。下列查询显示如何使用DECODE函数来针对employee表中的每 一行将evaluation列中的值转换为数字值。

图查询

SELECT emp_id, DECODE(evaluation, “poor”, 0, “fair”, 25, “good”,

50, “very good”, 75, “great”, 100, -1) AS evaluation FROM employee;

图:查询结果

emp_id

evaluation

012233

100

012344

0

012677

-1

012288

50

012555

75

可为DECODE函数的参数指定任何数据类型,只要这些参数满足以下需求:

参数test、a、b、…、n都具有相同的数据类型或求值为公共兼容的数据类型。

参数a_value、b_value、…、n_value都具有相同的数据类型或求值为公共兼容的数据类型。

NVL函数

可以使用NVL函数将求值为NULL的表达式转换为您指定的值。NVL函数接受两个参 数:第一个参数获取要求值的表达式的名称;第二个参数指定当第一个参数求值为NULL 时函数返回的值。如果第一个参数求值不为NULL,那么函数将返回第一个参数的值。假 设包括name和address列的student表存在。同时假设对student表执行以下查询。

图查询

SELECT name, address FROM student;

图:查询结果

name address

John Smith Lauren Collier Fred Frith Susan Jordan

333 Vista Drive

1129 Greenridge Street

NULL

NULL

以下是包括NVL函数的一个示例,该函数为表address列包含NULL值的每一行返回一个 新值。

图查询

SELECT name, NVL(address, “address is unknown”) AS address

FROM student;

图: 查询结果

name address

John Smith

333 Vista Drive

Lauren Collier

1129 Greenridge Street

Fred Frith

address is unknown

Susan Jordan

address is unknown

可以为NVL函数指定任何数据类型,只要这两个参数求值为公共兼容的数据类型。

如果NVL函数的两个参数都求值为NULL,那么函数返回NULL。

GBase 8s还支持NULLIF函数。该函数类似于NVL函数。但语义不同。如果其两个参数相 等,NULLIF返回NULL,或者两个参数不相等,将返回第一个参数。有关NULLIF函数 的更多信息,请参阅《GBase 8s SQL指南:语法》。

5.2 SELECT语句中的SPL例程

本章前面的示例显示由列名、运算符和SQL函数组成的SELECT语句表达式。本章提供 了包含SPL例程调用的表达式。

SPL例程包含特定的存储过程语言(SPL)语句和SQL语句。有关SPL例程的更多信息, 请参阅创建和使用SPL例程。

GBase 8s允许用C和Java™编写外部例程。有关更多信息,请参阅《GBase 8s用户定义 的例程和数据类型开发者指南》。

当您在投影列表中包含SPL例程表达式时,该SPL例程必须是返回单个值(一行一列) 的例程。例如:仅当test_func()返回单个值时,以下语句才有效:

SELECT col_a, test_func(col_b) FROM tabl

WHERE col_c = “Davis”;

当您在SELECT语句的Projection子句中包含SPL例程表达式时,该SPL例程必须是 返回单个值(一行一列)的例程。例如:仅当test_func()返回单个值时,数据库服务器返 回一个错误消息。returns more than one value, the database server returns an error message.

SPL例程通过允许您对选择的每行执行子查询来扩展可用函数的范围。

例如,假设您现有客户号、客户的姓和客户已下订单数的列表。下列查询查询了检索此信 息的一种方法。customer表具有customer_num和lname列,但没有每个客户已下订单数的 记录。可以编写get_orders例程,该例程查询每个customer_num的orders表并返回相应订 单的数目(标记为n_orders)。

图:查询

SELECT customer_num, lname, get_orders(customer_num) n_orders

FROM customer;

该结果显示了此SPL例程的输出。

图:查询结果

customer_num

lname

n_orders

101

Pauli

1

102

Sadler

9

103

Currie

9

104

Higgins

4

123

Hanlon

1

124

Putnum

1

125

Henry

0

126

Neelie

1

127

Satifer

1

128

Lessor

0

使用SPL例程来封装查询中经常执行的操作。例如:以下查询中的条件包括例 程conv_price,该例程将库存商品的单击转换为不同的货币并添加任何进口关税。

图:查询

SELECT stock_num, manu_code, description FROM stock

WHERE conv_price(unit_price, ex_rate = 1.50,

tariff = 50.00) < 1000;

5.3数据加密函数

您可以将SET ENCRYPTION PASSWORD语句与内置SQL加密函数(使用Advanced Encyption Standard (AES)和Triple DES (3DES)加密)一起使用来保护您的敏感数据。 如果使用加密,只有拥有正确密码的用户才能读取、复制或修改数据。

将SET ENCRYPTION PASSWORD语句与下列内置加密和解密函数一起使用:

ENCRYPT_AES
ENCRYPT_AES(data-string-expression

[,password-string-expression [, hint-string-expression ]])

ENCRYPT_TDES
ENCRYPT_TDES (data-string-expression

[,password-string-expression [, hint-string-expression ]])

DECRYPT_CHAR
DECRYPT_CHAR(EncryptedData [, PasswordOrPhrase])

DECRYPT_BINARY
DECRYPT_BINARY(EncryptedData [, PasswordOrPhrase])

GETHINT
GETHINT(EncryptedData)

如果您使用了 SET ENCRYPTION PASSWORD语句来指定缺省密码,那么数据库服务器 将该密码应用于同一会话中调用的对加密和解密函数的后续调用中。

使用ENCRYPT_AES和ENCRYPT_TDES定义加密的数据,使

用DECRYPT_CHAR和DECRYPT_BINARY查询加密的数据。使用GETHINT显示密码提 示符(如果在服务器上设置了该字符串)。

可以使用这些SQL内置函数来实现列级别或单元级别加密。

使用列级别加密,用相同的密码为给定列上的所有值加密。

使用单元级别加密,用不同的密码为列内的数据加密。

提示:如果想从大型表中选择加密数据,请指定未加密的列。在其中选择行,可对包含加密数 据的列创建索引或外键约束,但是这样做对资源使用的效率较低,原因是查询优化器不使用此 类索引和外键约束。

5.3.1使用列级别数据加密来保护信用卡数据

下列示例使用列级别加密来保护信用卡数据。

使用列级别加密来保护信用卡数据:

创建表:create table customer (id char(30), creditcard lvarchar(67));
插入加密数据:
设置会话密码:SET ENCRYPTION PASSWORD “credit card number is encrypted”;
加密数据。
INSERT INTO customer VALUES

(“Alice”, encrypt_aes(“1234567890123456”));

INSERT INTO customer VALUES

(“Bob”, encrypt_aes(“2345678901234567”));

使用解密函数查询加密数据。
SET ENCRYPTION PASSWORD “credit card number is encrypted”;

SELECT id FROM customer

WHERE DECRYPT_CHAR(creditcard) = “2345678901234567”; 重要:加密数据值比相应的未加密数据占用更多的存储空间。列宽足够存储明文的列可能需要 增大宽度才能支持列级别加密或单元级别加密。如果要将加密值插入声明宽度小于加密字符串 的列,那么列存储截断后的值,该值无法被解密。

有关加密安全性的更多信息,请参阅《GBase 8s管理员指南》。

有关内置加密和解密函数语法和存储要求的更多信息,请参阅《GBase 8s SQL指南:语法》。

5.4总结

本章介绍了在基本SELECT语句中用来查询关系数据库和处理返回数据的函数的样本语 法和结果。在SELECT语句中使用函数显示如何执行以下操作:

•在Projection子句中使用聚集函数来计算并检索特定数据。

• 在SELECT语句中包括时间函数 DATE、DAY、MDY、MONTH、 WEEKDAY、YEAR、CURRENT 和 EXTEND 以及 TODAY、LENGTH 和 USER函数。

•在SELECT子句中使用转换函数来在日期与字符串之间转换。

•在SELECT子句中使用字符串处理函数来转换大写和小写字母或以各种方法处理 字符串。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值