华为云用户手册

  • checksum(expression) 描述:返回所有输入值的CHECKSUM值。使用该函数可以用来验证 GaussDB (DWS)数据库(不支持GaussDB(DWS)之外的其他数据库)的备份恢复或者数据迁移操作前后表中的数据是否相同。在备份恢复或者数据迁移操作前后都需要用户通过手工执行SQL命令的方式获取执行结果,通过对比获取的执行结果判断操作前后表中的数据是否相同。 对于大表,CHECKSUM函数可能会需要很长时间。 如果某两表的CHECKSUM值不同,则表明两表的内容是不同的。由于CHECKSUM函数中使用散列函数不能保证无冲突,因此两个不同内容的表可能会得到相同的CHECKSUM值,存在这种情况的可能性较小。对于列进行的CHECKSUM也存在相同的情况。 对于时间类型timestamp, timestamptz和smalldatetime,计算CHECKSUM值时请确保时区设置一致。 若计算某列的CHECKSUM值,且该列类型可以默认转为TEXT类型,则expression为列名。 若计算某列的CHECKSUM值,且该列类型不能默认转为TEXT类型,则expression为列名::TEXT。 若计算所有列的CHECKSUM值,则expression为表名::TEXT。 可以默认转换为TEXT类型的类型包括:char, name, int8, int2, int1, int4, raw, pg_node_tree, float4, float8, bpchar, varchar, nvarchar2, date, timestamp, timestamptz, numeric, smalldatetime,其他类型需要强制转换为TEXT。 返回类型:numeric 示例: 表中可以默认转为TEXT类型的某列的CHECKSUM值: 1 2 3 4 5 SELECT CHECKSUM(inv_quantity_on_hand) FROM tpcds.inventory; checksum ------------------- 24417258945265247 (1 row) 表中不能默认转为TEXT类型的某列的CHECKSUM值(注意此时CHECKSUM参数是列名::TEXT): 1 2 3 4 5 SELECT CHECKSUM(inv_quantity_on_hand::TEXT) FROM tpcds.inventory; checksum ------------------- 24417258945265247 (1 row) 表中所有列的CHECKSUM值。注意此时CHECKSUM参数是表名::TEXT,且表名前不加Schema: 1 2 3 4 5 SELECT CHECKSUM(inventory::TEXT) FROM tpcds.inventory; checksum ------------------- 25223696246875800 (1 row)
  • approx_count_distinct(col_name) 描述:使用HyperLogLog++ (HLL++) 算法进行基数(某一列去重后的行数)的估算。该函数仅8.3.0及以上集群版本支持。 入参说明:col_name指需要估算基数的列。 可通过GUC参数approx_count_distinct_precision调整误差率。 参数取值范围为[10,20],默认值为17,理论误差率为千分之三。 该参数表示HyperLogLog++ (HLL++)算法中分桶个数,参数越大时,分桶数则越大,理论误差率则越小。 该参数取值越大,相应的计算时间和内存资源开销越大,但依然远小于精确的count distinct语句对应的开销。推荐在估算基数较大时使用该函数替换count distinct。 示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 CREATE TABLE employeeinfo (empno smallint, ename varchar(20), job varchar(20), hiredate date,deptno smallint) WITH (ORIENTATION = COLUMN); INSERT INTO employeeinfo VALUES (7155, 'JACK', 'SALESMAN', '2018-12-01', 30); INSERT INTO employeeinfo VALUES (7003, 'TOM', 'FINANCE', '2016-06-15', 20); INSERT INTO employeeinfo VALUES (7357, 'MAX', 'SALESMAN', '2020-10-01', 30); SELECT APPROX_COUNT_DISTINCT(empno) from employeeinfo; approx_count_distinct ----------------------- 3 (1 row) SELECT COUNT(DISTINCT empno) FROM employeeinfo GROUP BY ename; count ------- 1 1 1 (3 rows)
  • variance(expexpression,ression) 描述:var_samp的别名。 返回类型:对于浮点类型的输入返回double precision类型,其他输入返回numeric类型。 示例: 1 2 3 4 5 SELECT VARIANCE(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; variance -------------------- 83650.730277028768 (1 row)
  • var_pop(expression) 描述:总体方差(总体标准差的平方)。 返回类型:对于浮点类型的输入返回double precision类型,其他输入返回numeric类型。 示例: 1 2 3 4 5 SELECT VAR_POP(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; var_pop -------------------- 83650.692793695475 (1 row)
  • var_samp(expression) 描述:样本方差(样本标准差的平方)。 返回类型:对于浮点类型的输入返回double precision类型,其他输入返回numeric类型。 示例: 1 2 3 4 5 SELECT VAR_SAMP(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; var_samp -------------------- 83650.730277028768 (1 row)
  • group_concat(expression [ORDER BY {col_name | expr} [ASC | DESC]] [SEPARATOR str_val]) 描述:将列数据使用指定的str_val分隔符,按照ORDER BY子句指定的排序方式拼接成字符串,ORDER BY子句必须指定排序方式,不支持ORDER BY 1的写法。 expression:必选,指定列名或基于列的有效表达式,不支持DISTINCT关键字和VARIADIC参数。 str_val:可选,指定的分隔符,可以是字符串常数或基于分组列的确定性表达式。缺省时表示分隔符为逗号。 返回类型:text group_concat函数仅8.1.2及以上版本支持。 示例: 默认分隔符为逗号: 1 2 3 4 5 SELECT group_concat(sname) FROM group_concat_test; group_concat ------------------------------------------ ADAMS,FORD,JONES,KING,MILLER,SCOTT,SMITH (1 row) group_concat函数支持自定义分隔符: 1 2 3 4 5 SELECT group_concat(sname separator ';') from group_concat_test; group_concat ------------------------------------------ ADAMS;FORD;JONES;KING;MILLER;SCOTT;SMITH (1 row) group_concat函数支持ORDER BY子句,将列数据进行有序拼接: 1 2 3 4 5 SELECT group_concat(sname order by snumber separator ';') FROM group_concat_test; group_concat ------------------------------------------ MILLER;FORD;SCOTT;SMITH;KING;JONES;ADAMS (1 row)
  • stddev_pop(expression) 描述:总体标准差。 返回类型:对于浮点类型的输入返回double precision,其他输入返回numeric。 示例: 1 2 3 4 5 SELECT STDDEV_POP(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; stddev_pop ------------------ 289.224294957556 (1 row)
  • bit_and(expression) 描述:所有非NULL输入值的按位与(AND),如果全部输入值皆为NULL,那么结果也为NULL 。 返回类型:和参数数据类型相同。 示例: 1 2 3 4 5 SELECT BIT_AND(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; bit_and --------- 0 (1 row)
  • stddev_samp(expression) 描述:样本标准差。 返回类型:对于浮点类型的输入返回double precision,其他输入返回numeric。 示例: 1 2 3 4 5 SELECT STDDEV_SAMP(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; stddev_samp ------------------ 289.224359757315 (1 row)
  • bit_or(expression) 描述:所有非NULL输入值的按位或(OR),如果全部输入值皆为NULL,那么结果也为NULL。 返回类型:和参数数据类型相同 示例: 1 2 3 4 5 SELECT BIT_OR(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; bit_or -------- 1023 (1 row)
  • stddev(expression) 描述:stddev_samp的别名。 返回类型:对于浮点类型的输入返回double precision,其他输入返回numeric。 示例: 1 2 3 4 5 SELECT STDDEV(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; stddev ------------------ 289.224359757315 (1 row)
  • listagg(expression [, delimiter]) WITHIN GROUP(ORDER BY order-list) 描述:将聚集列数据按WITHIN GROUP指定的排序方式排列,并用delimiter指定的分隔符拼接成一个字符串。 expression:必选。指定聚集列名或基于列的有效表达式,不支持DISTINCT关键字和VARIADIC参数。 delimiter:可选。指定分隔符,可以是字符串常数或基于分组列的确定性表达式,缺省时表示分隔符为空。 order-list:必选。指定分组内的排序方式。 返回类型:text listagg是兼容Oracle 11g2的列转行聚集函数,可以指定OVER子句用作窗口函数。为了避免与函数本身WITHIN GROUP子句的ORDER BY造成二义性,listagg用作窗口函数时,OVER子句不支持ORDER BY的窗口排序或窗口框架。 示例: 聚集列是文本字符集类型: 1 2 3 4 5 6 7 SELECT deptno, listagg(ename, ',') WITHIN GROUP(ORDER BY ename) AS employees FROM emp GROUP BY deptno; deptno | employees --------+-------------------------------------- 10 | CLARK,KING,MILLER 20 | ADAMS,FORD,JONES,SCOTT,SMITH 30 | ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD (3 rows) 聚集列是整型: 1 2 3 4 5 6 7 SELECT deptno, listagg(mgrno, ',') WITHIN GROUP(ORDER BY mgrno NULLS FIRST) AS mgrnos FROM emp GROUP BY deptno; deptno | mgrnos --------+------------------------------- 10 | 7782,7839 20 | 7566,7566,7788,7839,7902 30 | 7698,7698,7698,7698,7698,7839 (3 rows) 聚集列是浮点类型: 1 2 3 4 5 6 7 8 9 SELECT job, listagg(bonus, '($); ') WITHIN GROUP(ORDER BY bonus DESC) || '($)' AS bonus FROM emp GROUP BY job; job | bonus ------------+------------------------------------------------- CLERK | 10234.21($); 2000.80($); 1100.00($); 1000.22($) PRESIDENT | 23011.88($) ANALYST | 2002.12($); 1001.01($) MANAGER | 10000.01($); 2399.50($); 999.10($) SALESMAN | 1000.01($); 899.00($); 99.99($); 9.00($) (5 rows) 聚集列是时间类型: 1 2 3 4 5 6 7 SELECT deptno, listagg(hiredate, ', ') WITHIN GROUP(ORDER BY hiredate DESC) AS hiredates FROM emp GROUP BY deptno; deptno | hiredates --------+------------------------------------------------------------------------------------------------------------------------------ 10 | 1982-01-23 00:00:00, 1981-11-17 00:00:00, 1981-06-09 00:00:00 20 | 2001-04-02 00:00:00, 1999-12-17 00:00:00, 1987-05-23 00:00:00, 1987-04-19 00:00:00, 1981-12-03 00:00:00 30 | 2015-02-20 00:00:00, 2010-02-22 00:00:00, 1997-09-28 00:00:00, 1981-12-03 00:00:00, 1981-09-08 00:00:00, 1981-05-01 00:00:00 (3 rows) 聚集列是时间间隔类型: 1 2 3 4 5 6 7 SELECT deptno, listagg(vacationTime, '; ') WITHIN GROUP(ORDER BY vacationTime DESC) AS vacationTime FROM emp GROUP BY deptno; deptno | vacationtime --------+------------------------------------------------------------------------------------ 10 | 1 year 30 days; 40 days; 10 days 20 | 70 days; 36 days; 9 days; 5 days 30 | 1 year 1 mon; 2 mons 10 days; 30 days; 12 days 12:00:00; 4 days 06:00:00; 24:00:00 (3 rows) 分隔符缺省时,默认为空: 1 2 3 4 5 6 7 SELECT deptno, listagg(job) WITHIN GROUP(ORDER BY job) AS jobs FROM emp GROUP BY deptno; deptno | jobs --------+---------------------------------------------- 10 | CLERKMANAGERPRESIDENT 20 | ANALYSTANALYSTCLERKCLERKMANAGER 30 | CLERKMANAGERSALESMANSALESMANSALESMANSALESMAN (3 rows) listagg作为窗口函数时,OVER子句不支持ORDER BY的窗口排序,listagg列为对应分组的有序聚集: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 SELECT deptno, mgrno, bonus, listagg(ename,'; ') WITHIN GROUP(ORDER BY hiredate) OVER(PARTITION BY deptno) AS employees FROM emp; deptno | mgrno | bonus | employees --------+-------+----------+------------------------------------------- 10 | 7839 | 10000.01 | CLARK; KING; MILLER 10 | | 23011.88 | CLARK; KING; MILLER 10 | 7782 | 10234.21 | CLARK; KING; MILLER 20 | 7566 | 2002.12 | FORD; SCOTT; ADAMS; SMITH; JONES 20 | 7566 | 1001.01 | FORD; SCOTT; ADAMS; SMITH; JONES 20 | 7788 | 1100.00 | FORD; SCOTT; ADAMS; SMITH; JONES 20 | 7902 | 2000.80 | FORD; SCOTT; ADAMS; SMITH; JONES 20 | 7839 | 999.10 | FORD; SCOTT; ADAMS; SMITH; JONES 30 | 7839 | 2399.50 | BLAKE; TURNER; JAMES; MARTIN; WARD; ALLEN 30 | 7698 | 9.00 | BLAKE; TURNER; JAMES; MARTIN; WARD; ALLEN 30 | 7698 | 1000.22 | BLAKE; TURNER; JAMES; MARTIN; WARD; ALLEN 30 | 7698 | 99.99 | BLAKE; TURNER; JAMES; MARTIN; WARD; ALLEN 30 | 7698 | 1000.01 | BLAKE; TURNER; JAMES; MARTIN; WARD; ALLEN 30 | 7698 | 899.00 | BLAKE; TURNER; JAMES; MARTIN; WARD; ALLEN (14 rows)
  • sum(expression) 描述:所有输入行的expression总和。 返回类型: 通常情况下输入数据类型和输出数据类型是相同的,但以下情况会发生类型转换: 对于SMALLINT或INT输入,输出类型为BIGINT。 对于BIGINT输入,输出类型为NUMBER 。 对于浮点数输入,输出类型为DOUBLE PRECISION。 示例: 1 2 3 4 5 SELECT SUM(ss_ext_tax) FROM tpcds.STORE_SALES; sum -------------- 213267594.69 (1 row)
  • array_agg(expression) 描述:将所有输入值(包括空)连接成一个数组。函数入参不支持数组形式。 返回类型:参数类型的数组。 示例: 创建表employeeinfo,并插入数据: 1 2 3 4 5 6 7 8 9 10 11 12 CREATE TABLE employeeinfo (empno smallint, ename varchar(20), job varchar(20), hiredate date,deptno smallint); INSERT INTO employeeinfo VALUES (7155, 'JACK', 'SALESMAN', '2018-12-01', 30); INSERT INTO employeeinfo VALUES (7003, 'TOM', 'FINANCE', '2016-06-15', 20); INSERT INTO employeeinfo VALUES (7357, 'MAX', 'SALESMAN', '2020-10-01', 30); SELECT * FROM employeeinfo; empno | ename | job | hiredate | deptno -------+-------+----------+---------------------+-------- 7155 | JACK | SALESMAN | 2018-12-01 00:00:00 | 30 7357 | MAX | SALESMAN | 2020-10-01 00:00:00 | 30 7003 | TOM | FINANCE | 2016-06-15 00:00:00 | 20 (3 rows) 查询部门编号为30的所有员工姓名: 1 2 3 4 5 SELECT array_agg(ename) FROM employeeinfo where deptno = 30; array_agg ------------ {JACK,MAX} (1 row) 查询属于同一个部门的所有员工: 1 2 3 4 5 6 7 8 9 10 11 12 13 SELECT deptno, array_agg(ename) FROM employeeinfo group by deptno; deptno | array_agg --------+------------ 30 | {JACK,MAX} 20 | {TOM} (2 rows) SELECT distinct array_agg(ename) OVER (PARTITION BY deptno) FROM employeeinfo; array_agg ------------ {TOM} {JACK,MAX} (2 rows) 查询所有的部门编号且去重: 1 2 3 4 5 6 SELECT array_agg(distinct deptno) FROM employeeinfo group by deptno; array_agg ----------- {20} {30} (2 rows) 查询所有的部门编号去重后按降序排列: 1 2 3 4 5 SELECT array_agg(distinct deptno order by deptno desc) FROM employeeinfo; array_agg ----------- {30,20} (1 row)
  • avg(expression) 描述:所有输入值的均值(算术平均)。 返回类型: 对于任何整数类型输入,结果都是NUMBER类型。 对于任何浮点输入,结果都是DOUBLE PRECISION类型。 其他,和输入数据类型相同。 示例: 1 2 3 4 5 SELECT AVG(inv_quantity_on_hand) FROM tpcds.inventory; avg ---------------------- 500.0387129084044604 (1 row)
  • percentile_cont(const) within group(order by expression) 描述:返回一个对应于目标列排序中指定分位数的值,如有必要就在相邻的输入项之间插入值。其中空值不参与计算。 输入:const为在0-1之间的数值,expression当前只支持数值类型和interval类型。 返回类型: 对于任何整型数据输入,结果都是NUMERIC类型。否则与输入数据类型相同。 Teradata兼容模式下,如果输入为整型,则返回的数据精度只有整数位。 示例: 1 2 3 4 5 6 7 8 9 10 SELECT percentile_cont(0.3) within group(order by x) FROM (SELECT generate_series(1,5) AS x) AS t; percentile_cont ----------------- 2.2 (1 row) SELECT percentile_cont(0.3) within group(order by x desc) FROM (SELECT generate_series(1,5) AS x) AS t; percentile_cont ----------------- 3.8 (1 row)
  • median(expression) 描述:所有输入值的中位数值。当前只支持数值类型和interval类型。其中空值不参与计算。 返回类型: 对于任何整型数据输入,结果都是NUMERIC类型。否则与输入数据类型相同。 Teradata兼容模式下,如果输入为整型,则返回的数据精度只有整数位。 示例: 1 2 3 4 5 SELECT MEDIAN(inv_quantity_on_hand) FROM tpcds.inventory; median -------- 500 (1 row)
  • percentile_disc(const) within group(order by expression) 描述:返回第一个在排序中位置等于或者超过指定分数的输入值。 输入:const为在0-1之间的数值,expression当前只支持数值类型和interval类型。其中空值不参与计算。 返回类型:对于任何整型数据输入,结果都是NUMERIC类型。否则,与输入数据类型相同。 示例: 1 2 3 4 5 6 7 8 9 10 SELECT percentile_disc(0.3) within group(order by x) FROM (SELECT generate_series(1,5) AS x) AS t; percentile_disc ----------------- 2 (1 row) SELECT percentile_disc(0.3) within group(order by x desc) FROM (SELECT generate_series(1,5) AS x) AS t; percentile_disc ----------------- 4 (1 row)
  • 示例 定义函数为SQL查询: 1 2 3 4 5 CREATE FUNCTION func_add_sql(integer, integer) RETURNS integer AS 'select $1 + $2;' LANGUAGE SQL IMMUTABLE RETURNS NULL ON NULL INPUT; 利用参数名用 PL/pgSQL 自增一个整数: 1 2 3 4 5 CREATE OR REPLACE FUNCTION func_increment_plsql(i integer) RETURNS integer AS $$ BEGIN RETURN i + 1; END; $$ LANGUAGE plpgsql; 返回RECORD类型: 1 2 3 4 5 6 7 8 9 CREATE OR REPLACE FUNCTION compute(i int, out result_1 bigint, out result_2 bigint) returns SETOF RECORD as $$ begin result_1 = i + 1; result_2 = i * 10; return next; end; $$language plpgsql; 返回一个包含多个输出参数的记录: 1 2 3 4 CREATE FUNCTION func_dup_sql(in int, out f1 int, out f2 text) AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$ LANGUAGE SQL; SELECT * FROM func_dup_sql(42); 计算两个整数的和,并返回结果。若果输入为null,则返回null: 1 2 3 4 5 6 CREATE FUNCTION func_add_sql2(num1 integer, num2 integer) RETURN integer AS BEGIN RETURN num1 + num2; END; / 创建package属性的重载函数: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 CREATE OR REPLACE FUNCTION package_func_overload(col int, col2 int) return integer package as declare col_type text; begin col := 122; dbms_output.put_line('two int parameters ' || col2); return 0; end; / CREATE OR REPLACE FUNCTION package_func_overload(col int, col2 smallint) return integer package as declare col_type text; begin col := 122; dbms_output.put_line('two smallint parameters ' || col2); return 0; end; /
  • 参数说明 function_name 要创建的函数名字(可以用模式修饰)。 取值范围:字符串,要符合标识符的命名规范。 如果创建的函数名与系统函数同名,建议指定schema。调用自定义函数时需指定schema,否则系统会优先调用系统函数。 argname 函数参数的名字。 取值范围:字符串,要符合标识符的命名规范。 argmode 函数参数的模式。 取值范围:IN,OUT,INOUT或VARIADIC。缺省值是IN。只有OUT模式的参数后面能跟VARIADIC。并且OUT和INOUT模式的参数不能用在RETURNS TABLE的函数定义中。 VARIADIC用于声明数组类型的参数。 argtype 函数参数的类型。 expression 函数参数的默认表达式。 rettype 函数返回值的数据类型。 如果存在OUT或IN OUT参数,可以省略RETURNS子句。如果存在,该子句必须和输出参数所表示的结果类型一致:如果有多个输出参数,则为RECORD,否则与单个输出参数的类型相同。 SETOF修饰词表示该函数将返回一个集合,而不是单独一项。 DETERMINISTIC 为适配Oracle SQL语法,未实现功能,不推荐使用。 column_name 字段名称。 column_type 字段类型。 definition 一个定义函数的字符串常量,含义取决于语言。它可以是一个内部函数名字、一个指向某个目标文件的路径、一个SQL查询、一个过程语言文本。 LANGUAGE lang_name 用以实现函数的语言的名字。可以是SQL,internal,或者是用户定义的过程语言名字。为了保证向下兼容,该名字可以用单引号(包围)。若采用单引号,则引号内必须为大写。 WINDOW 表示该函数是窗口函数,替换函数定义时不能改变WINDOW属性。 自定义窗口函数只支持LANGUAGE是internal,并且引用的内部函数必须是窗口函数。 IMMUTABLE 表示该函数在给出同样的参数值时总是返回同样的结果。 如果函数的入参是常量,会在优化器阶段计算该函数的值。益处是可以尽早获取表达式的值,从而能更准确的进行代价估算,生成的执行计划也更优。 用户自定义的IMMUTABLE的函数是会被自动下推到DN执行的,但是这样可能有潜在的风险,即如果用户错误定义了函数的IMMUTABLE属性,但是函数执行的过程并不是IMMUTABLE的,那么可能会导致结果错误等严重问题。因此,用户在指定函数的属性为IMMUTABLE的时候,要特别慎重。 举例如下: 如果自定义函数中引用了表,视图等对象,那么该函数就不能定义为IMMUTABLE,因为当表的数据发生变化的时候,函数的返回值可能发生变化。 如果自定义函数中引用了STABLE/VOALATILE类型的函数,那么该函数不能定义为IMMUTABLE。 如果自定义函数中有不下推的因素,则该函数不能定义成IMMUTABLE,因为IMMUTABLE意味着要下推到DN执行,与函数内部的不下推因素相互冲突。典型场景例如,包含不下推的函数、语法等。 如果自定义函数中含有聚合运算,但聚合运算的运算需要生成STREAM计划才能完成计算的(部分结果在DN计算,部分结果在CN计算,例如listagg函数等)。 同时,为了防止这种情况下可能出现严重问题,数据库内部可以通过设置behavior_compat_options=‘check_function_conflicts’来开启对函数定义冲突的检查,目前可以识别出上述1和2场景。 STABLE 表示该函数不能修改数据库,对相同参数值,在同一次表扫描里,该函数的返回值不变,但是返回值可能在不同SQL语句之间变化。 VOLATILE 表示该函数值可以在一次表扫描内改变,因此不会做任何优化。 SHIPPABLE NOT SHIPPABLE 表示该函数是否可以下推到DN上执行。 对于IMMUTABLE类型的函数,函数始终可以下推到DN上执行。 对于STABLE/VOLATILE类型的函数,仅当函数的属性是SHIPPABLE的时候,函数可以下推到DN执行。 用户在定义函数的SHIPPABLE属性时也需特别慎重,SHIPPABLE意味着整个函数会下推到DN上执行,如果设置不当,会导致结果错误等严重问题。 与定义IMMUTABLE属性一样,SHIPPABLE属性的定义也有诸多约束,简单来说就是函数内不能有不可下推的因素,函数下推到单DN执行后,函数内部的计算逻辑仅依赖当前DN的数据集合。 举例如下: 如果函数内部引用了表,并且表为HASH分布,那么该函数通常不能定义为SHIPPABLE。 函数内部有不可下推的因素,函数,语法等,那么该函数不能定义为SHIPPABLE,可参考语句下推调优。 函数内部的计算过程可能需要跨DN数据,这种情况该函数通常不能定义为SHIPPABLE,例如一些聚合运算等。 PACKAGE 表示该函数是否支持重载。PostgreSQL风格的函数本身就支持重载,此参数主要是针对Oracle风格的函数。 不允许package函数和非package函数重载或者替换。 package函数不支持VARIADIC类型的参数。 不允许修改函数的package属性。 LEAKPROOF 指出该函数的参数只包括返回值。LEAKPROOF只能由系统管理员设置。 CALLED ON NULL INPUT 表明该函数的某些参数是NULL的时候可以按照正常的方式调用。该参数可以省略。 RETURNS NULL ON NULL INPUT STRICT STRICT用于指定如果函数的某个参数是NULL,此函数总是返回NULL。如果声明了这个参数,当有NULL值参数时该函数不会被执行;而只是自动返回一个NULL结果。 RETURNS NULL ON NULL INPUT和STRICT的功能相同。 EXTERNAL 目的是和SQL兼容,是可选的,这个特性适合于所有函数,而不仅是外部函数。 SECURITY INVOKER AUTHID CURRENT_USER 表明该函数将带着调用它的用户的权限执行。该参数可以省略。 SECURITY INVOKER和AUTHID CURRENT_USER的功能相同。 SECURITY DEFINER AUTHID DEFINER 声明该函数将以创建它的用户的权限执行。 AUTHID DEFINER和SECURITY DEFINER的功能相同。 FENCED NOT FENCED 该函数只对用户定义的C函数生效,声明函数是在保护模式还是非保护模式下执行。如果函数声明为NOT FENCED模式,则函数的执行在CN或者DN进程中进行。如果函数声明为FENCED模式,则函数在新fork的进程执行,这样函数的异常不会影响CN或者DN进程。 FENCED/NOT FENCED模式的选择: 正在开发或者调试的Function使用FENCED模式。开发测试完成,使用NOT FENCED模式执行,减少fork进程以及通信的开销。 复杂的操作系统操作,例:打开文件,信号处理,线程处理等操作,使用FENCED模式。否则可能影响GaussDB(DWS)数据库的执行。 默认值为FENCED。 COST execution_cost 用来估计函数的执行成本。 execution_cost以cpu_operator_cost为单位。 取值范围:正数 ROWS result_rows 估计函数返回的行数。用于函数返回的是一个集合。 取值范围:正数,默认值是1000行。 configuration_parameter value 把指定的数据库会话参数值设置为给定的值。如果value是DEFAULT或者RESET,则在新的会话中使用系统的缺省设置。OFF关闭设置。 取值范围:字符串 DEFAULT OFF RESET 指定默认值。 from current 取当前会话中的值设置为configuration_parameter的值。 plsql_body PL/SQL存储过程体。 当在函数中创建用户时,日志中会记录密码的明文。因此不建议用户在函数中创建用户。
  • 注意事项 如果创建函数时参数或返回值带有精度,不进行精度检测。 创建函数时,函数定义中对表对象的操作建议都显式指定模式,否则可能会导致函数执行异常。 在创建函数时,函数内部通过SET语句设置current_schema和search_path无效。执行完函数search_path和current_schema与执行函数前的search_path和current_schema保持一致。 如果函数参数中带有出参,SELECT调用函数必须缺省出参,CALL调用函数适配Oracle必须指定出参,对于调用重载的带有PACKAGE属性的函数,CALL调用函数可以缺省出参,具体信息参见CALL的示例。 兼容PostgreSQL风格的函数或者带有PACKAGE属性的函数支持重载。在指定REPLACE的时候,如果参数个数、类型、返回值有变化,不会替换原有函数,而是会建立新的函数。 SELECT调用可以指定不同参数来进行同名函数调用。由于语法CALL适配自Oracle,因此不支持调用不带有PACKAGE属性的同名函数。 在创建function时,不能在avg函数外面嵌套其他agg函数,或者其他系统函数。 在非逻辑集群模式下,暂不支持将返回值、参数以及变量设置为建在非系统默认安装Node Group的表,sql function内部语句暂不支持对建在非系统默认安装Node Group的表操作。 在逻辑集群模式下,如果函数返回值和参数是用户表类型,所有涉及表都必须在同一逻辑集群内;如果函数内部涉及对多个逻辑集群表操作,函数定义时不能为IMMUTABLE和SHIPPABLE类型,以避免函数被下推到DN执行。 在逻辑集群模式下,函数参数、返回值不能用%type引用表字段类型,否则会导致函数创建失败。 新创建的函数默认会给PUBLIC授予执行权限(详见GRANT)。用户可以选择收回PUBLIC默认执行权限,然后根据需要将执行权限授予其他用户,为了避免出现新函数能被所有人访问的时间窗口,应在一个事务中创建函数并且设置函数执行权限。 在多个CN的集群中,不能将函数的入参或出参设置为临时表类型,因为在非当前连接CN上执行创建函数过程中,无法单独根据表名获取到正确的临时schema,进而无法获取到准确的表类型。
  • 语法格式 兼容PostgreSQL风格的创建自定义函数语法。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 CREATE [ OR REPLACE ] FUNCTION function_name ( [ { argname [ argmode ] argtype [ { DEFAULT | := | = } expression ]} [, ...] ] ) [ RETURNS rettype [ DETERMINISTIC ] | RETURNS TABLE ( { column_name column_type } [, ...] )] LANGUAGE lang_name [ {IMMUTABLE | STABLE | VOLATILE } | {SHIPPABLE | NOT SHIPPABLE} | WINDOW | [ NOT ] LEAKPROOF | {CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } | {[ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER | AUTHID DEFINER | AUTHID CURRENT_USER} | {FENCED | NOT FENCED} | {PACKAGE} | COST execution_cost | ROWS result_rows | SET configuration_parameter { {TO | =} value | FROM CURRENT }} ][...] { AS 'definition' | AS 'obj_file', 'link_symbol' } Oracle风格的创建自定义函数的语法。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 CREATE [ OR REPLACE ] FUNCTION function_name ( [ { argname [ argmode ] argtype [ { DEFAULT | := | = } expression ] } [, ...] ] ) RETURN rettype [ DETERMINISTIC ] [ {IMMUTABLE | STABLE | VOLATILE } | {SHIPPABLE | NOT SHIPPABLE} | {PACKAGE} | {FENCED | NOT FENCED} | [ NOT ] LEAKPROOF | {CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } | {[ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER | AUTHID DEFINER | AUTHID CURRENT_USER } | COST execution_cost | ROWS result_rows | SET configuration_parameter { {TO | =} value | FROM CURRENT ][...] { IS | AS } plsql_body /
  • inet inet类型在一个数据区域内保存主机的IPv4或IPv6地址,以及一个可选子网。主机地址中网络地址的位数表示子网(“子网掩码”)。如果子网掩码是32并且地址是IPv4,则这个值不表示任何子网,只表示一台主机。在IPv6里,地址长度是128位,因此128位表示唯一的主机地址。 该类型的输入格式是address/y,address表示IPv4或者IPv6地址,y是子网掩码的二进制位数。如果省略/y,则子网掩码对IPv4是32,对IPv6是128,所以该值表示只有一台主机。如果该值表示只有一台主机,/y将不会显示。 inet和cidr类型之间的基本区别是inet接受子网掩码,而cidr不接受。
  • macaddr macaddr类型存储MAC地址,也就是以太网卡硬件地址(尽管MAC地址还用于其它用途)。可以接受下列格式: '08:00:2b:01:02:03' '08-00-2b-01-02-03' '08002b:010203' '08002b-010203' '0800.2b01.0203' '08002b010203' 这些示例都表示同一个地址。对于数据位a到f,大小写都行。输出时都是以第一种形式展示。
  • cidr cidr(无类别域间路由,Classless Inter-Domain Routing)类型,保存一个IPv4或IPv6网络地址。声明网络格式为address/y,address表示IPv4或者IPv6地址,y表示子网掩码的二进制位数。如果省略y,则掩码部分使用已有类别的网络编号系统进行计算,但要求输入的数据已经包括了确定掩码所需的所有字节。 示例一:CIDR格式换算为IP地址网段 例如,10.0.0.0/8换算为32位二进制地址:00001010.00000000.00000000.00000000。其中/8表示8位网络ID,即32位二进制地址中前8位是固定不变的,对应网段为:00001010.00000000.00000000.00000000~00001010.11111111.11111111.11111111。则换算为十进制后,10.0.0.0/8表示:子网掩码为255.0.0.0,对应网段为10.0.0.0~10.255.255.255。 示例二:IP地址网段换算为CIDR格式 例如,192.168.0.0~192.168.31.255,后两段IP换算为二进制地址:00000000.00000000~00011111.11111111,可以得出前19位(8*2+3)是固定不变的,则换算为CIDR格式后,表示为:192.168.0.0/19。 表2 cidr类型输入举例 cidr输入 cidr输出 abbrev(cidr) 192.168.100.128/25 192.168.100.128/25 192.168.100.128/25 192.168/24 192.168.0.0/24 192.168.0/24 192.168/25 192.168.0.0/25 192.168.0.0/25 192.168.1 192.168.1.0/24 192.168.1/24 192.168 192.168.0.0/24 192.168.0/24 10.1.2 10.1.2.0/24 10.1.2/24 10.1 10.1.0.0/16 10.1/16 10 10.0.0.0/8 10/8 10.1.2.3/32 10.1.2.3/32 10.1.2.3/32 2001:4f8:3:ba::/64 2001:4f8:3:ba::/64 2001:4f8:3:ba::/64 2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128 2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128 2001:4f8:3:ba:2e0:81ff:fe22:d1f1
  • 枚举类型的安全性 每一种枚举数据类型都是独立的并且不能和其他枚举类型相比较。 1 2 3 4 5 6 7 8 9 10 11 12 CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic'); CREATE TABLE holidays (num_weeks integer, happiness happiness); INSERT INTO holidays(num_weeks,happiness) VALUES (4, 'happy'); INSERT INTO holidays(num_weeks,happiness) VALUES (6, 'very happy'); INSERT INTO holidays(num_weeks,happiness) VALUES (8, 'ecstatic'); INSERT INTO holidays(num_weeks,happiness) VALUES (2, 'sad'); ERROR: invalid input value for enum happiness: "sad" SELECT person.name, holidays.num_weeks FROM person, holidays WHERE person.current_mood = holidays.happiness; ERROR: operator does not exist: mood = happiness 如果需要作比较,可以使用自定义的操作符或者在查询中加上显式类型: 1 2 3 4 5 6 SELECT person.name, holidays.num_weeks FROM person, holidays WHERE person.current_mood::text = holidays.happiness::text; name | num_weeks ------+----------- Moe | 4 (1 row)
  • 枚举类型的声明 枚举类型可以使用CREATE TYPE命令创建,例如: 1 CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy'); 枚举类型被创建后,可以在表和函数定义中使用: 1 2 3 4 5 6 7 8 CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy'); CREATE TABLE person (name text, current_mood mood); INSERT INTO person VALUES ('Moe', 'happy'); SELECT * FROM person WHERE current_mood = 'happy'; name | current_mood ------+-------------- Moe | happy (1 row)
  • 参数说明 IF EXISTS 如果指定的函数不存在,则发出一个notice而不是抛出一个错误。 function_name 要删除的函数名字。 取值范围:已存在的函数名。 argmode 函数参数的模式。 argname 函数参数的名称。 argtype 函数参数的数据类型。 CASCADE | RESTRICT CASCADE:级联删除依赖于函数的对象(比如操作符) 。 RESTRICT:如果有任何依赖对象存在,则拒绝删除该函数(缺省行为)。
  • 参数说明 plan_hint子句 以/*+ */的形式在关键字后,用于对指定语句块生成的计划进行hint调优,详细用法请参见使用Plan Hint进行调优。 table_name 要更新的表名,可以使用模式修饰。 取值范围:已存在的表名称。 alias 目标表的别名。 取值范围:字符串,符合标识符命名规范。 column_name 要修改的字段名。 支持使用目标表的表名加字段名来引用这个字段。例如: 1 UPDATE foo SET foo.col_name = 'GaussDB'; 支持使用目标表的别名加字段名来引用这个字段。例如: 1 UPDATE foo AS f SET f.col_name = 'GaussDB'; 取值范围:已存在的字段名。 expression 赋给字段的值或表达式。 DEFAULT 用对应字段的缺省值填充该字段。 如果没有缺省值,则为NULL。 sub_query 子查询。 使用同一数据库里其他表的信息来更新一个表可以使用子查询的方法。其中SELECT子句具体介绍请参考SELECT。 from_list 一个表的表达式列表,允许在WHERE条件里使用其他表的字段。与在一个SELECT语句的FROM子句里声明表列表类似。 目标表绝对不能出现在from_list里,除非在使用一个自连接(此时它必须以from_list的别名出现)。 condition 一个返回boolean类型结果的表达式。只有这个表达式返回true的行才会被更新。 output_expression 在所有需要更新的行都被更新之后,UPDATE命令用于计算返回值的表达式。 取值范围:使用任何table以及FROM中列出的表的字段。*表示返回所有字段。 output_name 字段的返回名称。
  • 语法格式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 UPDATE [/*+ plan_hint */] [ ONLY ] table_name [ * ] [ [ AS ] alias ] SET {column_name = { expression | DEFAULT } |( column_name [, ...] ) = {( { expression | DEFAULT } [, ...] ) |sub_query }}[, ...] [ FROM from_list] [ WHERE condition ] [ RETURNING {* | {output_expression [ [ AS ] output_name ]} [, ...] }]; where sub_query can be: SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] { * | {expression [ [ AS ] output_name ]} [, ...] } [ FROM from_item [, ...] ] [ WHERE condition ] [ GROUP BY grouping_element [, ...] ] [ HAVING condition [, ...] ]
共100000条