华为云用户手册

  • 示例 1 2 3 4 5 6 7 8 9 10 11 --创建基本表table_for_label。 postgres=# CREATE TABLE table_for_label(col1 int, col2 text); --创建资源标签table_label。 postgres=# CREATE RESOURCE LABEL table_label ADD COLUMN(table_for_label.col1); --将col2添加至资源标签table_label中 postgres=# ALTER RESOURCE LABEL table_label ADD COLUMN(table_for_label.col2) --将资源标签table_label中的一项移除 postgres=# ALTER RESOURCE LABEL table_label REMOVE COLUMN(table_for_label.col1);
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 --演示在存储过程中对数组进行操作。 postgres=# CREATE OR REPLACE PROCEDURE array_proc AS TYPE ARRAY_INTEGER IS VARRAY(1024) OF INTEGER;--定义数组类型 ARRINT ARRAY_INTEGER := ARRAY_INTEGER(); --声明数组类型的变量 BEGIN ARRINT.extend(10); FOR I IN 1..10 LOOP ARRINT(I) := I; END LOOP; DBE_OUTPUT.PRINT_LINE(ARRINT.COUNT); DBE_OUTPUT.PRINT_LINE(ARRINT(1)); DBE_OUTPUT.PRINT_LINE(ARRINT(10)); DBE_OUTPUT.PRINT_LINE(ARRINT(ARRINT.FIRST)); DBE_OUTPUT.PRINT_LINE(ARRINT(ARRINT.last)); END; / --调用该存储过程。 postgres=# CALL array_proc(); --删除存储过程。 postgres=# DROP PROCEDURE array_proc;
  • 数组类型的使用 在使用数组之前,需要自定义一个数组类型。 在存储过程中紧跟AS关键字后面定义数组类型。定义方法为: TYPE array_type IS VARRAY(size) OF data_type; 其中: array_type:要定义的数组类型名。 VARRAY:表示要定义的数组类型。 size:取值为正整数,表示可以容纳的成员的最大数量。 data_type:要创建的数组中成员的类型。 在GaussDB中,数组会自动增长,访问越界会返回一个NULL,不会报错。 在存储过程中定义的数组类型,其作用域仅在该存储过程中。 建议选择上述定义方法的一种来自定义数组类型,当同时使用两种方法定义同名的数组类型时,GaussDB会优先选择存储过程中定义的数组类型来声明数组变量。 GaussDB支持使用圆括号来访问数组元素,且还支持一些特有的函数,如extend,count,first,last来访问数组的内容。 存储过程中如果有DML语句(SELECT、UPDATE、INSERT、DELETE),DML语句只能使用中括号来访问数组元素,这样可以和函数表达式区分开。
  • dynamic_library_path 参数说明:设置数据查找动态加载的共享库文件的路径。当需要打开一个可以动态装载的模块并且在CREATE FUNCTION或LOAD命令里面声明的名称没有目录部分时,系统将搜索这个目录以查找声明的文件,仅sysadmin用户可以访问。 用于dynamic_library_path的数值必须是一个冒号分隔(Windows下是分号分隔)的绝对路径列表。当一个路径名称以特殊变量$libdir为开头时,会替换为GaussDB发布提供的模块安装路径。例如: 1 dynamic_library_path = '/usr/local/lib/postgresql:/opt/testgs/lib:$libdir' 该参数属于SUSET类型参数,请参考重设参数中对应设置方法进行设置。 取值范围:字符串 设置为空字符串,表示关闭自动路径搜索。 默认值:$libdir
  • local_preload_libraries 参数说明:指定一个或多个共享库,它们在开始连接前预先加载。多个加载库之间用逗号分隔,除了双引号,所有的库名都转换为小写。 并非只有系统管理员才能更改此选项,因此只能加载安装的标准库目录下plugins子目录中的库文件,数据库管理员有责任确保该目录中的库都是安全的。local_preload_libraries中指定的项可以明确含有该目录,例如$libdir/plugins/mylib;也可以仅指定库的名称,例如mylib(等价于$libdir/plugins/mylib)。 与shared_preload_libraries不同,在会话开始之前加载模块与在会话中使用到该模块的时候临时加载相比并不具有性能优势。相反,这个特性的目的是为了调试或者测量在特定会话中不明确使用LOAD加载的库。例如针对某个用户将该参数设为ALTER USER SET来进行调试。 当指定的库未找到时,连接会失败。 每一个支持GaussDB的库都有一个“magic block”用于确保兼容性,因此不支持GaussDB的库不能通过这个方法加载。 该参数属于BACKEND类型参数,请参考重设参数中对应设置方法进行设置。 取值范围:字符串 默认值:空
  • 参数说明 WITH [ RECURSIVE ] with_query [, ...] 用于声明一个或多个可以在主查询中通过名称引用的子查询,相当于临时表。 如果声明了RECURSIVE,那么允许SELECT子查询通过名称引用它自己。 其中with_query的详细格式为:with_query_name [ ( column_name [, ...] ) ] AS ( {select | values | insert | update | delete} ) – with_query_name指定子查询生成的结果集名称,在查询中可使用该名称访问 子查询的结果集。 – column_name指定子查询结果集中显示的列名。 – 每个子查询可以是SELECT,VALUES,INSERT,UPDATE或DELETE语句。 INSERT ON DUPLICATE KEY UPDATE不支持WITH及WITH RECURSIVE子句。 table_name 要插入数据的目标表名。 取值范围:已存在的表名。 column_name 目标表中的字段名: 字段名可以有子字段名或者数组下标修饰。 没有在字段列表中出现的每个字段,将由系统默认值,或者声明时的默认值填充,若都没有则用NULL填充。例如,向一个复合类型中的某些字段插入数据的话,其他字段将是NULL。 目标字段(column_name)可以按顺序排列。如果没有列出任何字段,则默认全部字段,且顺序为表声明时的顺序。 如果value子句和query中只提供了N个字段,则目标字段为前N个字段。 value子句和query提供的值在表中从左到右关联到对应列。 取值范围:已存在的字段名。 expression 赋予对应column的一个有效表达式或值: 如果是INSERT ON DUPLICATE KEY UPDATE语句下,expression可以为VALUES(column_name)或EXCLUDED.column_name用来表示引用冲突行对应的column_name字段的值。需注意,其中VALUES(column_name)不支持嵌套在表达式中(例如VALUES(column_name)+1),但EXCLUDED不受此限制。 向表中字段插入单引号 " ' "时需要使用单引号自身进行转义。 如果插入行的表达式不是正确的数据类型,系统试图进行类型转换,若转换不成功,则插入数据失败,系统返回错误信息。 DEFAULT 对应字段名的缺省值。如果没有缺省值,则为NULL。 query 一个查询语句(SELECT语句),将查询结果作为插入的数据。 RETURNING 返回实际插入的行,RETURNING列表的语法与SELECT的输出列表一致。注意:INSERT ON DUPLICATE KEY UPDATE不支持RETURNING子句。 output_expression INSERT命令在每一行都被插入之后用于计算输出结果的表达式。 取值范围:该表达式可以使用table的任意字段。可以使用*返回被插入行的所有字段。 output_name 字段的输出名称。 取值范围:字符串,符合标识符命名规范。 ON DUPLICATE KEY UPDATE 对于带有唯一约束(UNIQUE INDEX或PRIMARY KEY)的表,如果插入数据违反唯一约束,则对冲突行执行UPDATE子句完成更新。如果UPDATE子句为NOTHING,则不做任何操作。 对于不带唯一约束的表,则仅执行插入。 不支持触发器,不会触发目标表的INSERT或UPDATE触发器。 不支持延迟生效(DEFERRABLE)的唯一约束或主键。 如果表中存在多个唯一约束,如果所插入数据违反多个唯一约束,对于检测到冲突的第一行进行更新,其他冲突行不更新(检查顺序与索引维护具有强相关性,一般先创建的索引先进行冲突检查)。 分布列、唯一索引列不允许UPDATE。 列存表不支持该操作就行。
  • 优化建议 VALUES 通过insert语句批量插入数据时,建议将多条记录合并入一条语句中执行插入,以提高数据加载性能。例如,INSERT INTO sections VALUES (30, 'Administration', 31, 1900),(40, 'Development', 35, 2000), (50, 'Development' , 60 , 2001); 如果insert多values语句中values的值分布在一个DN上,GaussDB可以把语句下推到对应DN执行。目前只支持values中值为常量,简单表达式和可下推函数(pg_proc中字段provolatile为'i')。如果表中列带有default值,只支持default值为常量,简单表达式。单values不能下推单DN的语句,多values同样不支持下推。
  • 语法格式 1 2 3 4 5 6 7 [ WITH [ RECURSIVE ] with_query [, ...] ] INSERT INTO table_name [ ( column_name [, ...] ) ] { DEFAULT VALUES | VALUES {( { expression | DEFAULT } [, ...] ) }[, ...] | query } [ ON DUPLICATE KEY UPDATE { NOTHING | column_name = { expression | DEFAULT } } [, ...] ] [ RETURNING {* | {output_expression [ [ AS ] output_name ] }[, ...]} ];
  • 注意事项 只有拥有表INSERT权限的用户,才可以向表中插入数据。 如果使用RETURNING子句,用户必须要有该表的SELECT权限。 如果使用ON DUPLICATE KEY UPDATE,用户必须要有该表的SELECT、UPDATE权限,唯一约束(主键或唯一索引)的SELECT权限。 如果使用query子句插入来自查询里的数据行,用户还需要拥有在查询里使用的表的SELECT权限。 如果使用query子句插入来自查询动态数据脱敏列的数据,插入的结果即为脱敏后的值,无法被还原。 当连接到TD兼容的数据库时,td_compatible_truncation参数设置为on时,将启用超长字符串自动截断功能,在后续的insert语句中(不包含外表的场景下),对目标表中char和varchar类型的列上插入超长字符串时,系统会自动按照目标表中相应列定义的最大长度对超长字符串进行截断。 如果向字符集为字节类型编码(SQL_ASCII,LATIN1等)的数据库中插入多字节字符数据(如汉字等),且字符数据跨越截断位置,这种情况下,按照字节长度自动截断,自动截断后会在尾部产生非预期结果。如果用户有对于截断结果正确性的要求,建议用户采用UTF8等能够按照字符截断的输入字符集作为数据库的编码集。
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 -- 创建一个资源池,其控制组指定为"DefaultClass"组下属的"High" Timeshare Workload控制组。 postgres=# CREATE RESOURCE POOL pool1 WITH (CONTROL_GROUP="High"); -- 创建一个负载组,关联已创建的资源池。 postgres=# CREATE WORKLOAD GROUP group1 USING RESOURCE POOL pool1; -- 创建一个应用映射组,关联已创建的负载组。 postgres=# CREATE APP WORKLOAD GROUP MAPPING app_wg_map1 WITH (WORKLOAD_GPNAME=group1); --创建一个默认应用映射组,关联默认的负载组。 postgres=# CREATE APP WORKLOAD GROUP MAPPING app_wg_map2; --删除应用映射组。 postgres=# DROP APP WORKLOAD GROUP MAPPING app_wg_map1; postgres=# DROP APP WORKLOAD GROUP MAPPING app_wg_map2; --删除负载组。 postgres=# DROP WORKLOAD GROUP group1; --删除资源池。 postgres=# DROP RESOURCE POOL pool1;
  • 步骤5:分析和处理错误表中的错误信息 对数据导入过程中出现的数据格式错误信息进行处理,若没有错误信息,此步骤可跳过。 查询错误信息。 1 postgres=# SELECT * FROM product_info_err ; 处理错误表中的错误信息。 按照本教程的示例操作,错误表中应该无错误信息。 您也可以将步骤2:在数据服务器上安装配置和启动GDS一节所建外表中的FILL_MISSING_FIELDS和IGNORE_EXTRA_DATA改为 'false'后,重新进行数据导入并查询错误表。此时,您将看到因如下原因带来的数据格式错误信息记录: 源数据文件product_info2.csv中第2条记录的最后一个字段“product_comment_content”缺失。 源数据文件product_info2.csv中第3条记录比外表定义列数多。 更多关于错误表及错误信息的处理请参见处理错误表。 父主题: 教程:使用GDS从远端服务器导入数据
  • 分词器测试 函数ts_debug允许简单测试文本搜索分词器。 1 2 3 4 5 6 7 8 ts_debug([ config regconfig, ] document text, OUT alias text, OUT description text, OUT token text, OUT dictionaries regdictionary[], OUT dictionary regdictionary, OUT lexemes text[]) returns setof record ts_debug显示document的每个token信息,token是由解析器生成,由指定的词典进行处理。如果忽略对应参数,则使用config指定的分词器或者default_text_search_config指定的分词器。 ts_debug为文本解析器标识的每个token返回一行记录。记录中的列分别是: alias:text类型,token的别名。 description:text类型,token的描述。 token:text类型,token的文本内容。 dictionaries:regdictionary数组类型,是分词器为token选定的词典。 dictionary:regdictionary类型,用来识别token的词典。如果为空,则不做识别。 lexemes:text数组类型,词典识别token时生成的词素。如果为空,则不生成词素。空数组({})意味着token将被识别成停用词。 一个简单的例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 postgres=# SELECT * FROM ts_debug('english','a fat cat sat on a mat - it ate a fat rats'); alias | description | token | dictionaries | dictionary | lexemes -----------+-----------------+-------+----------------+--------------+--------- asciiword | Word, all ASCII | a | {english_stem} | english_stem | {} blank | Space symbols | | {} | | asciiword | Word, all ASCII | fat | {english_stem} | english_stem | {fat} blank | Space symbols | | {} | | asciiword | Word, all ASCII | cat | {english_stem} | english_stem | {cat} blank | Space symbols | | {} | | asciiword | Word, all ASCII | sat | {english_stem} | english_stem | {sat} blank | Space symbols | | {} | | asciiword | Word, all ASCII | on | {english_stem} | english_stem | {} blank | Space symbols | | {} | | asciiword | Word, all ASCII | a | {english_stem} | english_stem | {} blank | Space symbols | | {} | | asciiword | Word, all ASCII | mat | {english_stem} | english_stem | {mat} blank | Space symbols | | {} | | blank | Space symbols | - | {} | | asciiword | Word, all ASCII | it | {english_stem} | english_stem | {} blank | Space symbols | | {} | | asciiword | Word, all ASCII | ate | {english_stem} | english_stem | {ate} blank | Space symbols | | {} | | asciiword | Word, all ASCII | a | {english_stem} | english_stem | {} blank | Space symbols | | {} | | asciiword | Word, all ASCII | fat | {english_stem} | english_stem | {fat} blank | Space symbols | | {} | | asciiword | Word, all ASCII | rats | {english_stem} | english_stem | {rat} (24 rows) 父主题: 测试和调试文本搜索
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 --撤销 my_savepoint 建立之后执行的命令的影响。 postgres=# START TRANSACTION; postgres=# SAVEPOINT my_savepoint; postgres=# ROLLBACK TO SAVEPOINT my_savepoint; --游标位置不受保存点回滚的影响。 postgres=# DECLARE foo CURSOR FOR SELECT 1 UNION SELECT 2; postgres=# SAVEPOINT foo; postgres=# FETCH 1 FROM foo; ?column? ---------- 1 postgres=# ROLLBACK TO SAVEPOINT foo; postgres=# FETCH 1 FROM foo; ?column? ---------- 2 postgres=# RELEASE SAVEPOINT my_savepoint; postgres=# COMMIT;
  • 注意事项 不能回滚到一个未定义的保存点,语法上会报错。 在保存点方面,游标有一些非事务性的行为。任何在保存点里打开的游标都会在回滚掉这个保存点之后关闭。如果一个前面打开了的游标在保存点里面,并且游标被一个FETCH命令影响,而这个保存点稍后回滚了,那么这个游标的位置仍然在FETCH让它指向的位置(也就是FETCH不会被回滚)。关闭一个游标的行为也不会被回滚给撤消掉。如果一个游标的操作导致事务回滚,那么这个游标就会置于不可执行状态,所以,尽管一个事务可以用ROLLBACK TO SAVEPOINT重新恢复,但是游标不能再使用了。 使用ROLLBACK TO SAVEPOINT回滚到一个保存点。使用RELEASE SAVEPOINT删除一个保存点,但是保留该保存点建立后执行的命令的效果。
  • Retry管理 Retry是数据库在SQL或存储过程(包含匿名块)执行失败时,在数据库内部进行重新执行的过程,以提高执行成功率和用户体验。数据库内部通过检查发生错误时的错误码及Retry相关配置,决定是否进行重试。 失败时回滚之前执行的语句,并重新执行存储过程进行Retry。 示例: 1 2 3 4 5 6 7 8 9 postgres=# CREATE OR REPLACE PROCEDURE retry_basic ( IN x INT) AS BEGIN INSERT INTO t1 (a) VALUES (x); INSERT INTO t1 (a) VALUES (x+1); END; / postgres=# CALL retry_basic(1); 父主题: 存储过程
  • 基本功能 连接数据库:可以通过gsql远程连接数据库实例。 gsql创建连接时,会有5分钟超时时间。如果在这个时间内,数据库未正确地接受连接并对身份进行认证,gsql将超时退出。 针对此问题,可以参考常见问题处理。 执行SQL语句:支持交互式地键入并执行SQL语句,也可以执行一个文件中指定的SQL语句。 执行元命令:元命令可以帮助管理员查看数据库对象的信息、查询缓存区信息、格式化SQL输出结果,以及连接到新的数据库等。元命令的详细说明请参见元命令参考。
  • 环境变量 表5 与gsql相关的环境变量 名称 描述 COLUMNS 如果\set columns为0,则由此参数控制wrapped格式的宽度。这个宽度用于决定在自动扩展的模式下,是否要把宽输出模式变成竖线的格式。 PAGER 如果查询结果无法在一页显示,它们就会被重定向到这个命令。可以用\pset命令关闭分页器。典型的是用命令more或less来实现逐页查看。缺省值是平台相关的。 说明: less的文本显示,受系统环境变量LC_CTYPE影响。 PSQL_EDITOR \e和\ef命令使用环境变量指定的编辑器。变量是按照列出的先后顺序检查的。在Unix系统上默认的编辑工具是vi。 EDITOR VISUAL PSQL_EDITOR_LINENUMBER_ARG 当\e和\ef带上一行数字参数使用时,这个变量指定的命令行参数用于向编辑器传递起始行数。像Emacs或vi这样的编辑器,这只是个加号。如果选项和行号之间需要空白,在变量的值后加一个空格。例如: PSQL_EDITOR_LINENUMBER_ARG = '+' PSQL_EDITOR_LINENUMBER_ARG='--line ' Unix系统默认的是+。 PSQLRC 用户的.gsqlrc文件的交互位置。 SHELL 使用\!命令跟shell执行的命令是一样的效果。 TMPDIR 存储临时文件的目录。缺省是/tmp。
  • date_part date_part函数是在传统的Ingres函数的基础上制作的(该函数等效于SQL标准函数extract): date_part('field', source) 这里的field参数必须是一个字符串,而不是一个名称。有效的field与extract一样,详细信息请参见EXTRACT。 示例: 1 2 3 4 5 postgres=# SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40'); date_part ----------- 16 (1 row) 1 2 3 4 5 postgres=# SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_part ----------- 4 (1 row)
  • TIMESTAMPDIFF TIMESTAMPDIFF(unit , timestamp_expr1, timestamp_expr2) timestampdiff函数是计算两个日期时间之间(timestamp_expr2-timestamp_expr1)的差值,并以unit形式范围结果。timestamp_expr1,timestamp_expr2必须是一个timestamp、timestamptz、date类型的值表达式。unit表示的是两个日期差的单位。 该函数仅在GaussDB Kernel兼容MySQL类型时(即dbcompatibility = 'MYSQL')有效,其他类型不支持该函数。 year 年份。 1 2 3 4 5 postgres=# SELECT TIMESTAMPDIFF(YEAR, '2018-01-01', '2020-01-01'); timestamp_diff ---------------- 2 (1 row)
  • EXTRACT EXTRACT(field FROM source) extract函数从日期或时间的数值里抽取子域,比如年、小时等。source必须是一个timestamp、time或interval类型的值表达式(类型为date的表达式转换为timestamp,因此也可以用)。field是一个标识符或者字符串,它指定从源数据中抽取的域。extract函数返回类型为double precision的数值。field的取值范围如下所示。 century 世纪。 第一个世纪从0001-01-01 00:00:00 AD开始。这个定义适用于所有使用阳历的国家。没有0世纪,直接从公元前1世纪到公元1世纪。 示例: 1 2 3 4 5 postgres=# SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13'); date_part ----------- 20 (1 row) day 如果source为timestamp,表示月份里的日期(1-31)。 1 2 3 4 5 postgres=# SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40'); date_part ----------- 16 (1 row) 如果source为interval,表示天数。 1 2 3 4 5 postgres=# SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute'); date_part ----------- 40 (1 row) decade 年份除以10。 1 2 3 4 5 postgres=# SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40'); date_part ----------- 200 (1 row) dow 每周的星期几,星期天(0)到星期六(6)。 1 2 3 4 5 postgres=# SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); date_part ----------- 5 (1 row) doy 一年的第几天(1~365/366)。 1 2 3 4 5 postgres=# SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); date_part ----------- 47 (1 row) epoch 如果source为timestamp with time zone,表示自1970-01-01 00:00:00-00 UTC以来的秒数(结果可能是负数); 如果source为date和timestamp,表示自1970-01-01 00:00:00-00当地时间以来的秒数; 如果source为interval,表示时间间隔的总秒数。 1 2 3 4 5 postgres=# SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08'); date_part -------------- 982384720.12 (1 row) 1 2 3 4 5 postgres=# SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours'); date_part ----------- 442800 (1 row) 将epoch值转换为时间戳的方法。 1 2 3 4 5 postgres=# SELECT TIMESTAMP WITH TIME ZONE 'epoch' + 982384720.12 * INTERVAL '1 second' AS RESULT; result --------------------------- 2001-02-17 12:38:40.12+08 (1 row) hour 小时域(0-23)。 1 2 3 4 5 postgres=# SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40'); date_part ----------- 20 (1 row) isodow 一周的第几天(1-7)。 星期一为1,星期天为7。 除了星期天外,都与dow相同。 1 2 3 4 5 postgres=# SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40'); date_part ----------- 7 (1 row) isoyear 日期中的ISO 8601标准年(不适用于间隔)。 每个带有星期一开始的周中包含1月4日的ISO年,所以在年初的1月或12月下旬的ISO年可能会不同于阳历的年。详细信息请参见后续的week描述。 1 2 3 4 5 6 7 8 9 10 gaussdb=# SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01'); date_part ----------- 2005 (1 row) gaussdb=# SELECT EXTRACT(WEEK FROM TIMESTAMP '2006-01-01 00:00:40'); date_part ----------- 52 (1 row) gaussdb=# SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); date_part ----------- 2006 (1 row) gaussdb=# SELECT EXTRACT(WEEK FROM TIMESTAMP '2006-01-02 00:00:40'); date_part ----------- 1 (1 row) microseconds 秒域(包括小数部分)乘以1,000,000。 1 2 3 4 5 postgres=# SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5'); date_part ----------- 28500000 (1 row) millennium 千年。 20世纪(19xx年)里面的年份在第二个千年里。第三个千年从2001年1月1日零时开始。 1 2 3 4 5 postgres=# SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40'); date_part ----------- 3 (1 row) milliseconds 秒域(包括小数部分)乘以1000。请注意它包括完整的秒。 1 2 3 4 5 postgres=# SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5'); date_part ----------- 28500 (1 row) minute 分钟域(0-59)。 1 2 3 4 5 postgres=# SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); date_part ----------- 38 (1 row) month 如果source为timestamp,表示一年里的月份数(1-12)。 1 2 3 4 5 postgres=# SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40'); date_part ----------- 2 (1 row) 如果source为interval,表示月的数目,然后对12取模(0-11)。 1 2 3 4 5 postgres=# SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); date_part ----------- 1 (1 row) quarter 该天所在的该年的季度(1-4)。 1 2 3 4 5 postgres=# SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40'); date_part ----------- 1 (1 row) second 秒域,包括小数部分(0-59)。 1 2 3 4 5 postgres=# SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); date_part ----------- 28.5 (1 row) timezone 与UTC的时区偏移量,单位为秒。正数对应UTC东边的时区,负数对应UTC西边的时区。 timezone_hour 时区偏移量的小时部分。 timezone_minute 时区偏移量的分钟部分。 week 该天在所在的年份里是第几周。ISO 8601定义一年的第一周包含该年的一月四日(ISO-8601 的周从星期一开始)。换句话说,一年的第一个星期四在第一周。 在ISO定义里,一月的头几天可能是前一年的第52或者第53周,十二月的后几天可能是下一年第一周。比如,2006-01-01是2005年的第52周,而2006-01-02是2006年的第1周。建议isoyear字段和week一起使用以得到一致的结果。 1 2 3 4 5 6 7 8 9 10 gaussdb=# SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01'); date_part ----------- 2005 (1 row) gaussdb=# SELECT EXTRACT(WEEK FROM TIMESTAMP '2006-01-01 00:00:40'); date_part ----------- 52 (1 row) gaussdb=# SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); date_part ----------- 2006 (1 row) gaussdb=# SELECT EXTRACT(WEEK FROM TIMESTAMP '2006-01-02 00:00:40'); date_part ----------- 1 (1 row) year 年份域。 1 2 3 4 5 postgres=# SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40'); date_part ----------- 2001 (1 row)
  • 时间/日期函数 age(timestamp, timestamp) 描述:将两个参数相减,并以年、月、日作为返回值。若相减值为负,则函数返回亦为负,入参可以都带timezone或都不带timezone。 返回值类型:interval 示例: 1 2 3 4 5 postgres=# SELECT age(timestamp '2001-04-10', timestamp '1957-06-13'); age ------------------------- 43 years 9 mons 27 days (1 row) age(timestamp) 描述:当前时间和参数相减,入参可以带或者不带timezone。 返回值类型:interval 示例: 1 2 3 4 5 postgres=# SELECT age(timestamp '1957-06-13'); age ------------------------- 60 years 2 mons 18 days (1 row) clock_timestamp() 描述:实时时钟的当前时间戳。volatile函数,每次扫描都会取最新的时间戳,因此在一次查询中每次调用结果不相同。 返回值类型:timestamp with time zone 示例: 1 2 3 4 5 postgres=# SELECT clock_timestamp(); clock_timestamp ------------------------------- 2017-09-01 16:57:36.636205+08 (1 row) current_date 描述:当前日期。 返回值类型:date 示例: 1 2 3 4 5 postgres=# SELECT current_date; date ------------ 2017-09-01 (1 row) current_time 描述:当前时间。 返回值类型:time with time zone 示例: 1 2 3 4 5 postgres=# SELECT current_time; timetz -------------------- 16:58:07.086215+08 (1 row) current_timestamp 描述:当前日期及时间。语句级别时间,同一个语句内返回结果不变。 返回值类型:timestamp with time zone 示例: 1 2 3 4 5 postgres=# SELECT current_timestamp; pg_systimestamp ------------------------------ 2017-09-01 16:58:19.22173+08 (1 row) date_part(text, timestamp) 描述: 获取日期或者时间值中子域的值,例如年或者小时的值。 等效于extract(field from timestamp)。 timestamp类型:abstime、date、interval、reltime、time with time zone、time without time zone、timestamp with time zone、timestamp without time zone。 返回值类型:double precision 示例: 1 2 3 4 5 postgres=# SELECT date_part('hour', timestamp '2001-02-16 20:38:40'); date_part ----------- 20 (1 row) date_part(text, interval) 描述:获取月份的值。如果大于12,则取与12的模。等效于extract(field from timestamp)。 返回值类型:double precision 示例: 1 2 3 4 5 postgres=# SELECT date_part('month', interval '2 years 3 months'); date_part ----------- 3 (1 row) date_trunc(text, timestamp) 描述:截取到参数text指定的精度。 返回值类型:interval、timestamp with time zone、timestamp without time zone 示例: 1 2 3 4 5 postgres=# SELECT date_trunc('hour', timestamp '2001-02-16 20:38:40'); date_trunc --------------------- 2001-02-16 20:00:00 (1 row) trunc(timestamp) 描述:默认按天截取。 示例: 1 2 3 4 postgres=# SELECT trunc(timestamp '2001-02-16 20:38:40'); trunc --------------------- 2001-02-16 00:00:00 (1 row) daterange(arg1, arg2) 描述:获取时间边界信息。 arg1类型:date arg2类型:date 返回值类型:daterange 示例: 1 2 3 4 5 postgres=# select daterange('2000-05-06','2000-08-08'); daterange ------------------------- [2000-05-06,2000-08-08) (1 row) daterange(arg1, arg2, text) 描述:获取时间边界信息。 arg1类型:date arg2类型:date text类型:text 返回值类型:daterange 示例: 1 2 3 4 5 postgres=# select daterange('2000-05-06','2000-08-08','[]'); daterange ------------------------- [2000-05-06,2000-08-09) (1 row) extract(field from timestamp) 描述:获取小时的值。 返回值类型:double precision 示例: 1 2 3 4 5 postgres=# SELECT extract(hour from timestamp '2001-02-16 20:38:40'); date_part ----------- 20 (1 row) extract(field from interval) 描述:获取月份的值。如果大于12,则取与12的模。 返回值类型:double precision 示例: 1 2 3 4 5 postgres=# SELECT extract(month from interval '2 years 3 months'); date_part ----------- 3 (1 row) isfinite(date) 描述:测试是否为有效日期。 返回值类型:Boolean 示例: 1 2 3 4 5 postgres=# SELECT isfinite(date '2001-02-16'); isfinite ---------- t (1 row) isfinite(timestamp) 描述:测试判断是否为有效时间。 返回值类型:Boolean 示例: 1 2 3 4 5 postgres=# SELECT isfinite(timestamp '2001-02-16 21:28:30'); isfinite ---------- t (1 row) isfinite(interval) 描述:测试是否为有效区间。 返回值类型:Boolean 示例: 1 2 3 4 5 postgres=# SELECT isfinite(interval '4 hours'); isfinite ---------- t (1 row) justify_days(interval) 描述:将时间间隔以月(30天为一月)为单位。 返回值类型:interval 示例: 1 2 3 4 5 postgres=# SELECT justify_days(interval '35 days'); justify_days -------------- 1 mon 5 days (1 row) justify_hours(interval) 描述:将时间间隔以天(24小时为一天)为单位。 返回值类型:interval 示例: 1 2 3 4 5 postgres=# SELECT JUSTIFY_HOURS(INTERVAL '27 HOURS'); justify_hours ---------------- 1 day 03:00:00 (1 row) justify_interval(interval) 描述:结合justify_days和justify_hours,调整interval。 返回值类型:interval 示例: 1 2 3 4 5 postgres=# SELECT JUSTIFY_INTERVAL(INTERVAL '1 MON -1 HOUR'); justify_interval ------------------ 29 days 23:00:00 (1 row) localtime 描述:当前时间。 返回值类型:time 示例: 1 2 3 4 5 postgres=# SELECT localtime AS RESULT; result ---------------- 16:05:55.664681 (1 row) localtimestamp 描述:当前日期及时间。 返回值类型:timestamp 示例: 1 2 3 4 5 postgres=# SELECT localtimestamp; timestamp ---------------------------- 2017-09-01 17:03:30.781902 (1 row) now() 描述:当前日期及时间。事务级别时间,同一个事务内返回结果相同。 返回值类型:timestamp with time zone 示例: 1 2 3 4 5 postgres=# SELECT now(); now ------------------------------- 2017-09-01 17:03:42.549426+08 (1 row) timenow 描述:当前日期及时间。语句级别时间,同一个语句内返回结果不变。 返回值类型:timestamp with time zone 示例: 1 2 3 4 5 postgres=# select timenow(); timenow ------------------------ 2020-06-23 20:36:56+08 (1 row) numtodsinterval(num, interval_unit) 描述:将数字转换为interval类型。num为numeric类型数字,interval_unit为固定格式字符串('DAY' | 'HOUR' | 'MINUTE' | 'SECOND')。 可以通过设置参数IntervalStyle为oracle,兼容该函数在Oracle中的interval输出格式。 示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 postgres=# SELECT numtodsinterval(100, 'HOUR'); numtodsinterval ----------------- 100:00:00 (1 row) postgres=# SET intervalstyle = oracle; SET postgres=# SELECT numtodsinterval(100, 'HOUR'); numtodsinterval ------------------------------- +000000004 04:00:00.000000000 (1 row) pg_sleep(seconds) 描述:服务器线程延迟时间,单位为秒。 返回值类型:void 示例: 1 2 3 4 5 postgres=# SELECT pg_sleep(10); pg_sleep ---------- (1 row) statement_timestamp() 描述:当前日期及时间。 返回值类型:timestamp with time zone 示例: 1 2 3 4 5 postgres=# SELECT statement_timestamp(); statement_timestamp ------------------------------- 2017-09-01 17:04:39.119267+08 (1 row) sysdate 描述:当前日期及时间。 返回值类型:timestamp 示例: 1 2 3 4 5 postgres=# SELECT sysdate; sysdate --------------------- 2017-09-01 17:04:49 (1 row) timeofday() 描述:当前日期及时间(像clock_timestamp,但是返回时为text)。 返回值类型:text 示例: 1 2 3 4 5 postgres=# SELECT timeofday(); timeofday ------------------------------------- Fri Sep 01 17:05:01.167506 2017 CST (1 row) transaction_timestamp() 描述:当前日期及时间,与current_timestamp等效。 返回值类型:timestamp with time zone 示例: 1 2 3 4 5 postgres=# SELECT transaction_timestamp(); transaction_timestamp ------------------------------- 2017-09-01 17:05:13.534454+08 (1 row) add_months(d,n) 描述:用于计算时间点d再加上n个月的时间。 返回值类型:timestamp 示例: 1 2 3 4 5 postgres=# SELECT add_months(to_date('2017-5-29', 'yyyy-mm-dd'), 11) FROM sys_dummy; add_months --------------------- 2018-04-29 00:00:00 (1 row) last_day(d) 描述:用于计算时间点d当月最后一天的时间。 返回值类型:timestamp 示例: 1 2 3 4 5 postgres=# select last_day(to_date('2017-01-01', 'YYYY-MM-DD')) AS cal_result; cal_result --------------------- 2017-01-31 00:00:00 (1 row)
  • 原型 1 2 3 4 5 6 SQLRETURN SQLGetData(SQLHSTMT StatementHandle, SQLUSMALLINT Col_or_Param_Num, SQLSMALLINT TargetType, SQLPOINTER TargetValuePtr, SQLLEN BufferLength, SQLLEN *StrLen_or_IndPtr);
  • 参数 表1 SQLGetData参数 关键字 参数说明 StatementHandle 语句句柄,通过SQLAllocHandle获得。 Col_or_Param_Num 要返回数据的列号。结果集的列按增序从1开始编号。书签列的列号为0。 TargetType TargetValuePtr缓冲中的C数据类型的类型标识符。若TargetType为SQL_ARD_TYPE,驱动使用ARD中SQL_DESC_CONCISE_TYPE字段的类型标识符。若为SQL_C_DEFAULT,驱动根据源的SQL数据类型选择缺省的数据类型。 TargetValuePtr 输出参数:指向返回数据所在缓冲区的指针。 BufferLength TargetValuePtr所指向缓冲区的长度。 StrLen_or_IndPtr 输出参数:指向缓冲区的指针,在此缓冲区中返回长度或标识符的值。
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 下面存储过程中用到的表定义如下: postgres=# \d emp_rec Table "public.emp_rec" Column | Type | Modifiers ----------+--------------------------------+----------- empno | numeric(4,0) | not null ename | character varying(10) | job | character varying(9) | mgr | numeric(4,0) | hiredate | timestamp(0) without time zone | sal | numeric(7,2) | comm | numeric(7,2) | deptno | numeric(2,0) | --演示在存储过程中对数组进行操作。 postgres=# CREATE OR REPLACE FUNCTION regress_record(p_w VARCHAR2) RETURNS VARCHAR2 AS $$ DECLARE --声明一个record类型. type rec_type is record (name varchar2(100), epno int); employer rec_type; --使用%type声明record类型 type rec_type1 is record (name emp_rec.ename%type, epno int not null :=10); employer1 rec_type1; --声明带有默认值的record类型 type rec_type2 is record ( name varchar2 not null := 'SCOTT', epno int not null :=10); employer2 rec_type2; CURSOR C1 IS select ename,empno from emp_rec order by 1 limit 1; BEGIN --对一个record类型的变量的成员赋值。 employer.name := 'WARD'; employer.epno = 18; raise info 'employer name: % , epno:%', employer.name, employer.epno; --将一个record类型的变量赋值给另一个变量。 employer1 := employer; raise info 'employer1 name: % , epno: %',employer1.name, employer1.epno; --将一个record类型变量赋值为NULL。 employer1 := NULL; raise info 'employer1 name: % , epno: %',employer1.name, employer1.epno; --获取record变量的默认值。 raise info 'employer2 name: % ,epno: %', employer2.name, employer2.epno; --在for循环中使用record变量 for employer in select ename,empno from emp_rec order by 1 limit 1 loop raise info 'employer name: % , epno: %', employer.name, employer.epno; end loop; --在select into 中使用record变量。 select ename,empno into employer2 from emp_rec order by 1 limit 1; raise info 'employer name: % , epno: %', employer2.name, employer2.epno; --在cursor中使用record变量。 OPEN C1; FETCH C1 INTO employer2; raise info 'employer name: % , epno: %', employer2.name, employer2.epno; CLOSE C1; RETURN employer.name; END; $$ LANGUAGE plpgsql; --调用该存储过程。 postgres=# CALL regress_record('abc'); --删除存储过程。 postgres=# DROP PROCEDURE regress_record;
  • 操作步骤 创建源表products,并插入数据。 1 2 3 4 5 6 7 8 9 10 11 postgres=# CREATE TABLE products ( product_id INTEGER, product_name VARCHAR2(60), category VARCHAR2(60) ); postgres=# INSERT INTO products VALUES (1502, 'olympus camera', 'electrncs'), (1601, 'lamaze', 'toys'), (1666, 'harry potter', 'toys'), (1700, 'wait interface', 'books'); 创建目标表newproducts,并插入数据。 1 2 3 4 5 6 7 8 9 10 11 12 postgres=# CREATE TABLE newproducts ( product_id INTEGER, product_name VARCHAR2(60), category VARCHAR2(60) ); postgres=# INSERT INTO newproducts VALUES (1501, 'vivitar 35mm', 'electrncs'), (1502, 'olympus ', 'electrncs'), (1600, 'play gym', 'toys'), (1601, 'lamaze', 'toys'), (1666, 'harry potter', 'dvd'); 使用MERGE INTO 语句将源表products的数据合并至目标表newproducts。 1 2 3 4 5 6 7 postgres=# MERGE INTO newproducts np USING products p ON (np.product_id = p.product_id ) WHEN MATCHED THEN UPDATE SET np.product_name = p.product_name, np.category = p.category WHEN NOT MATCHED THEN INSERT VALUES (p.product_id, p.product_name, p.category) ; 上述语句中使用的参数说明,请见表1。更多信息,请参见MERGE INTO。 表1 MERGE INTO语句参数说明 参数 说明 举例 INTO 子句 指定需要更新或插入数据的目标表。 目标表支持指定别名。 目标表支持复制表,但复制表不能带有含volatile函数的列(如自增列);如果enable_stream_operator=off,目标复制表需要带有主键或某一列满足unique not null约束。 取值:newproducts np 说明:名为newproducts,别名为np的目标表。 USING子句 指定源表。源表支持指定别名。 目标表是复制表时,源表也需要是复制表。 取值:products p 名为products,别名为p的源表。 ON子句 指定目标表和源表的关联条件。 关联条件中的字段不支持更新。 取值:np.product_id = p.product_id 说明:指定的关联条件为,目标表newproducts的product_id字段和源表products的product_id字段相等。 WHEN MATCHED子句 当源表和目标表中数据针对关联条件可以匹配上时,选择WHEN MATCHED子句进行UPDATE操作。 仅支持指定一个WHEN MATCHED子句。 WHEN MATCHED子句可缺省,缺省时,对于满足ON子句条件的行,不进行任何操作。 若目标表中存在分布列,则该列不支持更新。 取值:WHEN MATCHED THEN UPDATE SET np.product_name = p.product_name, np.category = p.category 说明:当满足ON子句条件时,将目标表newproducts的product_name、category字段的值替换为源表products相对应字段的值。 WHEN NOT MATCHED子句 当源表和目标表中数据针对关联条件无法匹配时,选择WHEN NOT MATCHED子句进行INSERT操作。 仅支持指定一个WHEN NOT MATCHED子句。 WHEN NOT MATCHED子句可缺省。 不支持INSERT子句中包含多个VALUES。 WHEN MATCHED和WHEN NOT MATCHED子句顺序可以交换,可以缺省其中一个,但不能同时缺省。 取值:WHEN NOT MATCHED THEN INSERT VALUES (p.product_id, p.product_name, p.category) 说明:将源表products中,不满足ON子句条件的行插入目标表products。 查询合并后的目标表newproducts。 1 postgres=# SELECT * FROM newproducts; 返回信息如下: product_id | product_name | category ------------+----------------+----------- 1501 | vivitar 35mm | electrncs 1502 | olympus camera | electrncs 1666 | harry potter | toys 1600 | play gym | toys 1601 | lamaze | toys 1700 | wait interface | books (6 rows)
  • 语法 语法请参见图1。 图1 call_anonymous_block::= using_clause子句的语法参见图2。 图2 using_clause::= 对以上语法格式的解释如下: 匿名块程序实施部分,以BEGIN语句开始,以END语句停顿,以一个分号结束。 USING [IN|OUT|IN OUT] bind_argument,用于指定存放传递给存储过程参数值的变量。bind_argument前的修饰符与对应参数的修饰符一致。 匿名块中间的输入输出参数使用占位符来指明,要求占位符个数与参数个数相同,并且占位符所对应参数的顺序和USING中参数的顺序一致。 目前GaussDB在动态语句调用匿名块时,EXCEPTION语句中暂不支持使用占位符进行输入输出参数的传递。 不支持调用带有占位符的重载函数。 不支持绑定参数时使用PERFORM关键字调用存储过程。 不支持同一条语句同时使用匿名块内声明的变量和绑定参数。 仅支持匿名块中调用SQL语句绑定参数,其余绑定参数场景皆不支持。例如:匿名块中调用存储过程,匿名块中使用表达式以及cursor等、匿名块中嵌套调用动态语句。
  • 参数说明 参数 参数说明 ctx 表示给定的上下文。 query 被执行的SQL语句。 args 被执行SQL语句需要绑定的参数。支持按位置绑定和按名称绑定,详情见如下示例。 opts 事务隔离级别和事务访问模式,其中事务隔离级别(opts.Isolation)支持范围为sql.LevelReadUncommitted,sql.LevelReadCommitted,sql.LevelRepeatableRead,sql.LevelSerializable。事务访问模式(opts.ReadOnly)支持范围为true(read only)和false(read write)。
  • macaddr函数 函数trunc(macaddr)返回一个MAC地址,该地址的最后三个字节设置为零。 trunc(macaddr) 描述:把后三个字节置为零。 返回类型:macaddr 示例: 1 2 3 4 5 gaussdb=# SELECT trunc(macaddr '12:34:56:78:90:ab') AS RESULT; result ------------------- 12:34:56:00:00:00 (1 row)
  • 注意事项 不能在该循环语句中对查询的表进行更新操作。 变量loop_name会自动定义且只在此循环中有效,类型和select_statement的查询结果类型一致。loop_name的取值就是select_statement的查询结果。 变量loop_name在编译过程中不会解析具体的类型,如果有需要解析具体类型的场景(比如loop_name作为重载函数或者存储过程的出入参)会编译报错。如需解析变量的具体类型,可以设置参数behavior_compat_options值为allow_procedure_compile_check。
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 BEGIN FOR ROW_TRANS IN SELECT first_name FROM hr.staffs LOOP DBE_OUTPUT.PRINT_LINE (ROW_TRANS.first_name ); END LOOP; END; / --创建表 CREATE TABLE integerTable1( A INTEGER); CREATE TABLE integerTable2( B INTEGER); INSERT INTO integerTable2 VALUES(2); --多游标共享游标属性的标量 DECLARE CURSOR C1 IS SELECT A FROM integerTable1;--声明游标 CURSOR C2 IS SELECT B FROM integerTable2; PI_A INTEGER; PI_B INTEGER; BEGIN OPEN C1;--打开游标 OPEN C2; FETCH C1 INTO PI_A; ---- C1%FOUND 和 C2%FOUND 值为 FALSE FETCH C2 INTO PI_B; ---- C1%FOUND 和 C2%FOUND 的值都为 TRUE --判断游标状态 IF C1%FOUND THEN IF C2%FOUND THEN DBE_OUTPUT.PRINT_LINE('Dual cursor share paremeter.'); END IF; END IF; CLOSE C1;--关闭游标 CLOSE C2; END; / --删除临时表 DROP TABLE integerTable1; DROP TABLE integerTable2;
共100000条