
# 操作指导
#### 前置操作
- 连接GaussDB数据库时，需要在远程数据库节点机器上设置允许DATABASE LINK进行访问，并配置远程连接。某些情况集群白名单中也需要添加DN的IP。
- 创建DATABASE LINK。
  - 创建DATABASE LINK对象，具体语法请参见《参考》中"SQL参考 \> SQL语法 \> C \> CREATE DATABASE LINK"章节。
  
  - 创建DATABASE LINK时可指定PUBLIC或PRIVATE，PRIVATE DATABASE LINK仅能被创建者进行访问，PUBLIC DATABASE LINK可被所有用户进行访问。所有已创建的DATABASE LINK信息都存放在本地数据库的系统视图GS_DB_LINKS中。
   
- 修改DATABASE LINK信息。 修改指定DATABASE LINK对象信息，具体语法请参见《参考》中"SQL参考 \> SQL语法 \> A \> ALTER DATABASE LINK"章节。
  
- 删除指定DATABASE LINK。 删除指定DATABASE LINK对象，具体语法请参见《参考》中"SQL参考 \> SQL语法 \> D \> DROP DATABASE LINK"语句。
  
- 通过DATABASE LINK进行SELECT操作。
  ```
  [ WITH [ RECURSIVE ] with_query [, ...] ]
   SELECT [/*+ plan_hint */] [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
   { * | {expression [ [ AS ] output_name ]} [, ...] }
   [ FROM from_item [, ...] ]
   [ WHERE condition ]
   [ [ START WITH condition ] CONNECT BY [NOCYCLE] condition [ ORDER SIBLINGS BY expression ] ]
   [ GROUP BY grouping_element [, ...] ]
   [ HAVING condition [, ...] ]
   [ { UNION | INTERSECT | EXCEPT | MINUS } [ ALL | DISTINCT ] select ]
   [ ORDER BY {expression [ [ ASC | DESC | USING operator ] | nlssort_expression_clause ] [ NULLS { FIRST | LAST } ]} [, ...] ]
   [ LIMIT { [offset,] count | ALL } ]
   [ OFFSET start [ ROW | ROWS ] ]
   [ {FOR { UPDATE | SHARE  } [ OF table_name [, ...] ] } [...] ];
   {[ ONLY ] table_name [ * ] @ dblink [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
    |( select ) [ AS ] alias [ ( column_alias [, ...] ) ]
    |with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
    | [function_name] ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ]
    | [function_name] ( [ argument [, ...] ] ) AS ( column_definition [, ...] )
    |from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]};
  ```
  
- 通过DATABASE LINK进行INSERT操作。
  ```
  [ WITH [ RECURSIVE ] with_query [, ...] ]
    INSERT [/*+ plan_hint */] INTO table_name @ dblink [ ( column_name [, ...] ) ]
       { DEFAULT VALUES
       | VALUES {( { expression | DEFAULT } [, ...] ) }[, ...] 
       | query }
       [ RETURNING { {output_expression [ [ AS ] output_name ] }[, ...]} ];
  ```
  
- 通过DATABASE LINK进行UPDATE操作。
  ```
  UPDATE [/*+ plan_hint */] [ ONLY ] table_name @ dblink [ [ AS ] alias ]
   SET {column_name = { expression | DEFAULT } 
      |( column_name [, ...] ) = {( { expression | DEFAULT } [, ...] ) |sub_query }}[, ...]
      [ FROM from_list] [ WHERE condition ]
      [ ORDER BY {expression [ [ ASC | DESC | USING operator ] | nlssort_expression_clause ] [ NULLS { FIRST | LAST } ]} [, ...] ]
      [ LIMIT { [offset,] count | ALL } ]
      [ 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 [, ...] ];
  ```
  
- 通过DATABASE LINK进行DELETE操作。
  ```
  [ WITH [ RECURSIVE ] with_query [, ...] ]
   DELETE [/*+ plan_hint */] FROM [ ONLY ] table_name @ dblink [ [ AS ] alias ]
      [ USING using_list ]
      [ WHERE condition]
      [ ORDER BY {expression [ [ ASC | DESC | USING operator ] | nlssort_expression_clause ] [ NULLS { FIRST | LAST } ]} [, ...] ]
      [ LIMIT { [offset,] count | ALL } ]
      [ RETURNING { { output_expr [ [ AS ] output_name ] } [, ...] } ];
  ```
  
- 通过DATABASE LINK进行LOCK TABLE操作。
  ```
  LOCK [ TABLE ] {[ ONLY ] name @ dblink  [, ...]}
      [ IN {ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE} MODE ]
      [ NOWAIT ];
  ```
  
- 调用远程数据库的存储过程或函数。
  ```
  CALL | SELECT [ schema. ] { func_name@dblink | procedure_name@dblink } ( param_expr );
  ```
  
![](https://support.huaweicloud.com/distributed-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
- 使用已创建的DATABASE LINK对远程数据库对象进行访问的语法和访问本地对象的语法基本一致，区别在于，当访问远程数据库对象时，需在被访问的远程数据库对象名称后添加@dblink。SQL语句具体支持情况存在部分约束条件，具体请参见[表2]。
- 上述语法中SQL语句涉及到的DATABASE LINK无关参数含义与原SQL语句中含义相同。
- 执行涉及到远程表的连接查询，需要指定列名时，可以在列名后添加"@dblink"，表示指定的列为DATABASE LINK指向的远程表的列，远程表的列不支持\*写法，如：remote_t1.\*@dblink。
 
 #### 规格约束
- 兼容性约束
  - DATABASE LINK特性仅在ORA兼容模式数据库下可以使用。
  
  - DATABASE LINK特性只支持连接GaussDB。
  
  - 当通过DATABASE LINK连接GaussDB时，用户需要保证本地和远程数据库的兼容性参数DBCOMPATIBILITY和GUC参数behavior_compat_options、a_format_dev_version、a_format_version取值一致。
  
  
  
  - 连接GaussDB时，DATABASE LINK开启远程连接事务前，会自动设置如下GUC参数：
    ```
    SET search_path=pg_catalog, '$user', 'public';
    SET explain_perf_mode='normal';
    SET session_timeout=0;
    SET datestyle=ISO;
    SET intervalstyle=postgres;
    SET extra_float_digits=3;
    ```
    ![](https://support.huaweicloud.com/distributed-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
    其余参数为远程数据库设置的参数，远程参数与本地参数不同时，可能会出现数据显示格式不一致等情况，使用时应尽量保证远程与本地参数相同。
    
  
  - 连接GaussDB时，远程数据库与本地数据库需要保证相同的datea类型，GUC参数mapping_date_to_datea才能正常使用。
   
- 字符集约束 当连接GaussDB时，如果本地数据库和远程数据库字符集不同，可能会出现无法转换，并返回远程的报错信息的情况。当本地数据库字符编码为GB18030_2022时，发送到远程的请求字符编码会被转换为GB18030。因此，若本地数据库的字符集为GB18030_2022时，远程数据库字符集只能是GB18030或GB18030_2022。
  
- 权限约束
  - 禁止使用DATABASE LINK连接初始用户。禁止初始用户进行创建、修改和删除DATABASE LINK对象的操作。
  
  - 创建DATABASE LINK权限需要使用GRANT语法赋予，新建用户默认无权限，系统管理员拥有权限。具体请参见《参考》中"SQL参考 \> SQL语法 \> G \> GRANT"章节。
  
  - 当赋予用户创建DATABASE LINK权限时，即默认许可用户使用远程数据库的IP地址对其进行访问。若不希望存在该情况，请不要使用GRANT对用户赋权。
  
  
  
  - 本地用户对DATABASE LINK的使用权限： 如果指定了PUBLIC关键词，即为公有的DATABASE LINK，可以被所有用户/模式使用。
    如果未指定PUBLIC关键词，就是私有的DATABASE LINK，仅能被当前用户/模式使用（包括SYSADMIN用户也无法跨Schema使用DATABASE LINK）。
    
  
  - 通过DATABASE LINK访问远程数据库对象的权限： 通过DATABASE LINK绑定的远程连接用户的权限，进行远程数据库对象的访问。
    
   
- 连接约束
  - 当未指定CURRENT_USER或CONNECT TO连接串时（即使用当前数据库初始用户名和空的密码连接），会连接失败。
  
  - 非透明多写特性下，使用本机IP及对应端口可连接当前实例数据库。由于CN和DN可能分布在不同服务器中，建议host参数不要使用127.0.0.1和localhost，可能会出现连接失败的情况。
  
  - DATABASE LINK创建时，不会对其是否可连接成功进行验证，如果缺乏相关的关键字，可能会在使用时报错。
  
  - 如果在创建DATABASE LINK对象后重新生成密钥文件，使用DATABASE LINK时将会报错。因为创建DATABASE LINK时使用的密钥文件与后续解密时使用的密钥文件不一致。
  
  - OPTION选项中conn_opt不支持设置密码且传入的libpq参数不能和原有参数重复。
   
- 升级约束 升级未提交情况下，无法创建使用DATABASE LINK。
  
- 元数据和锁相关约束
  - 使用DATABASE LINK对远程表操作时，会在本地创建与远程对应的Schema，若本地不存在该表的元数据信息，会将元数据信息写入本地系统表中，此时会使用7级锁保证写入的一致性，持续到事务结束后释放锁，删除DATABASE LINK时会将相应的元数据信息删除。
  
  - 使用DATABASE LINK时，在本地创建的表仅用于存储远程表的元数据信息，无法通过\\d或pg_get_tabledef函数查询该表的结构。
  
  - 如果业务中存在长事务首次使用DATABASE LINK操作远程对象时，会持续持锁直到事务结束，其他首次使用DATABASE LINK的事务会被阻塞。可通过对远程对象进行简单查询操作，使其元数据快速缓存到本地进行规避该情况。另外，远程表结构发生变化时，本地要更新存储的元数据信息，也会有类似阻塞情况。
  
  - 在本地创建与远程对应的Schema时，本地的Schema名称长度上限为63，格式为"*\[username#\]* *远程Schema* @*dblink_name*"，其中DATABASE LINK为PRIVATE时，username#不可省略。
  
  - 由于部分谓词无法下推，通过DATABASE LINK在使用UPDATE、DELETE及FOR UPDATE功能时，加锁的范围可能会扩大，可通过打印计划查询下推语句判断加锁范围。
  
  - 使用DATABASE LINK对远程表操作时，会创建一个单节点的node group随机绑定一个DN。
   
- 事务约束 使用DATABASE LINK时，本地事务和远程事务存下以下关系：
  - 本地事务会同步控制远程事务的提交/回滚状态。
  
  - 隔离级别的对应关系如[表1]所示。
     表1连接非透明多写特性下GaussDB数据库隔离级别对应关系表 
    | 本地隔离级别           | 远程隔离级别          |
    |:---|:---|
    | Read Uncommitted | Repeatable Read |
    | Read Committed   | Repeatable Read |
    | Repeatable Read  | Repeatable Read |
    | Serializable     | Serializable    |
       
    ![](https://support.huaweicloud.com/distributed-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
    - 本地事务提交过程中会向远程发送事务提交请求，如果远程事务提交成功后出现异常情况导致本地的事务提交失败（如连接异常、本地集群实例异常等情况），远程的事务提交无法被撤回，可能出现本地事务与远程事务不一致的情况。
    
    - DATABASE LINK不支持XA协议接口，可能出现本地事务与远程事务不一致的情况。
      
   
- 支持SQL范围约束
  - DATABASE LINK相关语句支持的情况如[表2]所示。
  
  - DATABASE LINK相关表类型支持情况如[表3]所示。
   
- DATABASE LINK函数和存储过程调用约束
  - 仅在非透明多写特性下支持通过DATABASE LINK连接调用远程函数或者存储过程。
  
  - 当通过DATABASE LINK调用远程数据库中的函数时，本地数据库需创建与远程函数名称和参数列表完全一致的函数，若远程函数存在重载，则需要在本地数据库创建对应的所有重载函数，否则会导致参数匹配失败。
  
  - DATABASE LINK调用远程数据库的存储过程和函数时，参数或返回值类型不能包含自定义类型，不支持OUT/INOUT参数或有默认值的参数，并且不能为PACKAGE内函数、聚集函数、窗口函数以及返回集合的函数；不支持使用SELECT \* FROM func@dblink();形式调用远程函数。
  
  - PLSQL_BODY内通过DATABASE LINK调用远程数据库的存储过程或函数时，参数或返回值类型不能包含自定义类型，不支持OUT/INOUT参数或有默认值的参数，并且不能为PACKAGE内函数、重载函数、聚集函数、窗口函数以及返回集合的函数。
  
  - DATABASE LINK调用远程数据库的存储过程和函数不指定Schema，默认调用PUBLIC下的函数或存储过程。
  
  - DATABASE LINK调用远程数据库的存储过程和函数时，参数列表不支持通过":="或者"=\>"的方式为参数赋值。
  
  
  ![](https://support.huaweicloud.com/distributed-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - PLSQL_BODY内调用远程数据库的存储过程或函数时，应使用\[CALL \| SELECT\] \[ schema. \] { func_name@dblink \| procedure_name@dblink } ( param_expr )的语法格式调用。
  
  - PLSQL_BODY内调用远程数据库的无参存储过程或函数时，应使用\[CALL \| SELECT\] \[ schema. \] { func_name@dblink \| procedure_name@dblink } ( )的语法格式调用。
    
- 同义词
  - 不支持将DATABASE LINK名创建为一个同义词的使用方法。
  
  - 当使用DATABASE LINK访问的远程对象创建为同名词时，若未指定远程对象的Schema，则默认采用创建同义词的当前Schema作为远程对象的Schema。
  
  - 不支持通过DATABASE LINK调用远程数据库中指向一个DATABASE LINK对象的同义词。例如：
    1. 在数据库a（db1）中创建表a（table1）。
    
    2. 在数据库b（db2）中创建连接数据库a（db1）的DATABASE LINK对象（dblink1），并创建同义词（CREATE SYNONYM table11 FOR user1.table1@dblink1";）。
    
    3. 在数据库c（db3）创建连接数据库b（db2）的DATABASE LINK对象（dblink2），通过dblink2调用数据库b（db2）上的同义词table11（执行SELECT \* FROM table11 @dblink2;，会返回"If the remote synonym is a dblink object, dblink access is not supported"的报错信息）。
     
  
  - 创建同义词的注意事项请参见《参考》中 "SQL参考 \> SQL语法 \> C \> CREATE SYNONYM"章节。
   
- 表类型约束
  连接GaussDB时，表类型约束如下：
  - HASHBUCKET：不支持通过DATABASE LINK对远程Hash bucket表进行查询或DML操作。
  
  - SLICE：不支持通过DATABASE LINK对远程SLICE表进行查询或DML操作。
  
  - 复制表：不支持通过DATABASE LINK对远程复制表进行查询或DML操作。
  
  - TEMPORARY：不支持通过DATABASE LINK对远程临时表进行查询或DML操作。
    
- 视图约束
  目前支持对DATABASE LINK的远程表创建视图，当远程表本身的结构发生变化时，该视图使用时会触发视图重编译，支持视图失效重编译后均为该行为，不受参数enable_view_invalidation影响。例如：
  1. 在数据库db1中创建表table1。
  
  2. 在数据库db2中创建连接数据库db1的DATABASE LINK对象dblink1，并创建视图view1（CREATE VIEW view1 AS SELECT \* FROM table1@dblink1;）。
  
  3. 在数据库db1中删除表table1的一列，在数据库db2上查询视图view1会重编译该视图，且重编译失败，并产生重编译失败报错。
  
  4. 在数据库db1中恢复表table1删除列，在数据库db2上查询视图view1会重编译该视图，且重编译成功，并正常返回查询结果。
   
  ![](https://support.huaweicloud.com/distributed-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  视图失效重编译及相关参数说明请参见[失效重编译](https://support.huaweicloud.com/distributed-devg-v10-gaussdb/gaussdb-12-0775.html)章节。
  
- 其他场景
  - DATABASE LINK表不支持触发器，包括触发器调用函数内使用DATABASE LINK场景、触发器调用函数为DATABASE LINK函数、在DATABASE LINK上定义触发器等情况。
  
  - 暂不支持UPSERT、MERGE语法。
  
  - 不支持CURRENT CURSOR语法。
  
  - 不支持查询表的隐藏字段。
  
  - 不支持DATABASE LINK访问远端类型。
  
  - 直连DN无法使用DATABASE LINK功能。
   
- DUMP与备份约束
  - 不支持DATABASE LINK相关数据库对象的DUMP，备机不支持DATABASE LINK调用，也不支持被DATABASE LINK连接。
  
  - 不支持DATABASE LINK相关数据库对象的集群备份后恢复使用。因为不同集群的密钥文件不同，在使用 DATABASE LINK 时需要使用集群密钥文件进行解密。
   
- JOIN下推约束 DATABASE LINK不支持JOIN下推。
  
- 谓词下推约束
  - 仅支持WHERE子句使用数据库内置的数据类型、操作符和函数，并且使用的函数为IMMUTABLE类型。
  
  - 不支持WHERE子句中同时使用到多张表的条件下推。
   
- 聚集函数下推约束 仅支持单表且没有GROUP子句、ORDER BY子句、HAVING子句、LIMIT子句的SELECT语句，并且不支持窗口函数。
  
- HINT下推
  支持针对DATABASE LINK表对象的Hint条件下推，仅限Scan方式的Hint下推，语法格式如下：
  ```
  [no] tablescan|indexscan|indexonlyscan(table [index])
  ```
  并要求在一个queryblock中的表名或表别名不能重复。
   表2支持SQL范围 
  | SQL类型           | 操作对象            | 支持选项说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 执行上下文                    |
  |:---|:---|:---|:---|
  | 创建DATABASE LINK | DATABASE LINK   | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | 普通事务块、存储过程、函数以及高级包。      |
  | 修改DATABASE LINK | DATABASE LINK   | 仅支持用户名、密码的修改。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | 普通事务块、存储过程、函数以及高级包。      |
  | 删除DATABASE LINK | DATABASE LINK   | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | 普通事务块、存储过程、函数以及高级包。      |
  | SELECT语句        | 普通表、普通视图、全量物化视图 | - WHERE子句  - DATABASE LINK表和内部表JOIN  - DATABASE LINK表和DATABASE LINK表JOIN  - 聚集函数  - ORDER BY子句  - WINDOW子句  - LIMIT、OFFSET、FETCH子句  - GROUP BY子句、HAVING子句  - UNION子句  - WITH子句  - START WITH子句和CONNECT BY子句  - ROWNUM使用  - PIVOT子句  - UNPIVOT子句  - FOR UPDATE子句 说明： 仅支持FOR UPDATE、FOR UPDATE NOWAIT、 FOR UPDATE WAIT用法。    | 普通事务块、存储过程、函数、高级包以及逻辑视图。 |
  | INSERT语句        | 普通表             | - WITH子句  - 多VALUE插入  - RETURNING子句   说明： - 不支持ON DUPLICATE KEY UPDATE子句。  - 不支持INSERT ALL语句。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | 普通事务块、存储过程、函数以及高级包。      |
  | UPDATE语句        | 普通表             | - WITH子句  - LIMIT子句  - ORDER BY子句  - WHERE子句  - RETURNING子句   说明： 不支持多表UPDATE操作。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | 普通事务块、存储过程、函数以及高级包。      |
  | DELETE语句        | 普通表             | - WITH子句  - LIMIT子句  - ORDER BY子句  - WHERE子句  - RETURNING子句   说明： 不支持多表DELETE操作。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | 普通事务块、存储过程、函数以及高级包。      |
  | LOCK TABLE语句    | 普通表             | - LOCKMODE子句  - NOWAIT子句                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 普通事务块。                   |
     
  ![](https://support.huaweicloud.com/distributed-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  对于分区表，支持PARTITION子句指定分区。
   表3连接非透明多写特性的GaussDB数据库表类型支持范围 
  | 维度         | GaussDB表类型 || DATABASE LINK支持情况 |
  |:---|:---|---|:---|
  | TEMP选项     | 临时表        || 不支持。              |
  | TEMP选项     | 全局临时表      || 不支持。              |
  | UNLOGGED选项 | 非日志表       || 支持。               |
  | 存储特性       | 行存 | Astore | 支持。               |
  | 存储特性       | 行存 | Ustore | 不支持。              |
  | 存储特性       | 分区表        || 不支持。              |
  | 存储特性       | 二级分区表      || 不支持。              |
  | 视图         | DATABASE LINK访问远程视图 || 支持SELECT，不支持DML。  |
  | 视图         | 本地视图通过DATABASE LINK关联远程表 || 支持SELECT，不支持DML。  |
     
  
 
#### 使用示例
连接GaussDB数据库
```
-- DATABASE LINK相关DDL语句。
-- 前置操作。
gaussdb=# CREATE USER jack WITH PASSWORD '********';
CREATE ROLE
-- 赋予用户创建DATABASE LINK对象的权限。
gaussdb=# GRANT CREATE PUBLIC DATABASE LINK TO jack;
GRANT
-- 赋予用户删除DATABASE LINK对象的权限。
gaussdb=# GRANT DROP PUBLIC DATABASE LINK TO jack;
GRANT ROLE
-- 赋予用户修改DATABASE LINK对象的权限。
gaussdb=# GRANT ALTER PUBLIC DATABASE LINK TO jack;
GRANT ROLE
-- 回收用户创建DATABASE LINK对象的权限。
gaussdb=# REVOKE CREATE PUBLIC DATABASE LINK FROM jack;
REVOKE
-- 回收用户删除DATABASE LINK对象的权限。
gaussdb=# REVOKE DROP PUBLIC DATABASE LINK FROM jack;
REVOKE ROLE
-- 回收用户修改DATABASE LINK对象的权限。
gaussdb=# REVOKE ALTER PUBLIC DATABASE LINK FROM jack;
REVOKE ROLE
-- 清理环境。
gaussdb=# DROP USER jack;
DROP ROLE
-- 前置操作。
-- 创建一个兼容性为ORA的数据库。
gaussdb=# CREATE DATABASE ora_test_db DBCOMPATIBILITY 'ORA';
CREATE DATABASE
-- 切换数据库。
gaussdb=# \c ora_test_db
-- 创建拥有系统管理员权限的用户。
ora_test_db=# CREATE USER local_user WITH SYSADMIN PASSWORD '********';
CREATE ROLE
ora_test_db=# SET ROLE local_user PASSWORD '********';
SET
-- 创建DATABASE LINK对象，host也可以是IPv6地址。
ora_test_db=> CREATE PUBLIC DATABASE LINK dblink CONNECT TO 'remote_user' IDENTIFIED BY '********' USING (host '***.***.***.***', port '*****', dbname 'remote_db');
CREATE DATABASE LINK
-- 修改DATABASE LINK信息。
ora_test_db=> ALTER PUBLIC DATABASE LINK dblink CONNECT TO 'remote_user' IDENTIFIED BY '********';
ALTER DATABASE LINK
-- 删除DATABASE LINK对象。
ora_test_db=> DROP PUBLIC DATABASE LINK dblink;
DROP DATABASE LINK
-- 清理环境。
ora_test_db=> RESET ROLE;
RESET
ora_test_db=# DROP USER local_user;
DROP ROLE
ora_test_db=# \c postgres
gaussdb=# DROP DATABASE ora_test_db;
DROP DATABASE
-- DATABASE LINK具体操作语句。
-- 前置操作。
gaussdb=# CREATE USER local_user WITH SYSADMIN PASSWORD '********';
CREATE ROLE
gaussdb=# CREATE USER remote_user WITH SYSADMIN PASSWORD '********';
CREATE ROLE
-- 创建远程数据库。
gaussdb=# CREATE DATABASE remote_db DBCOMPATIBILITY = 'ORA'; 
CREATE DATABASE
-- 创建测试DATABASE LINK数据库。
gaussdb=# CREATE DATABASE local_db DBCOMPATIBILITY = 'ORA';  
CREATE DATABASE
gaussdb=# \c remote_db
remote_db=# SET ROLE remote_user PASSWORD '********';
SET
remote_db=> CREATE SCHEMA remote_user;
CREATE SCHEMA
-- 创建普通表。
remote_db=> CREATE TABLE remote_tb(f1 int, f2 text, f3 text[]) WITH (STORAGE_TYPE = ASTORE);
CREATE TABLE
remote_db=> INSERT INTO remote_tb VALUES (0,'a','{"a0","b0","c0"}');
INSERT 0 1
remote_db=> INSERT INTO remote_tb VALUES (1,'bb','{"a1","b1","c1"}');
INSERT 0 1
remote_db=> INSERT INTO remote_tb VALUES (2,'cc','{"a2","b2","c2"}');
INSERT 0 1
-- 创建函数。
remote_db=> CREATE OR REPLACE FUNCTION f(a in int, b in int)
RETURN int AS
    tmp int :=  a + b;
BEGIN
    RETURN tmp;
END;
/
CREATE FUNCTION
-- 创建同义词。
remote_db=> CREATE SYNONYM remote_sy FOR remote_tb;
CREATE SYNONYM
remote_db=> \c local_db
local_db=# SET ROLE local_user PASSWORD '********';
SET
local_db=> CREATE SCHEMA local_user;
CREATE SCHEMA
local_db=> CREATE TABLE local_tb(f1 int, f2 text, f3 text[]) WITH (STORAGE_TYPE = ASTORE);
CREATE TABLE
local_db=> INSERT INTO local_tb VALUES (2,'c','{"a2","b2","c2"}');
INSERT 0 1
local_db=> CREATE PUBLIC DATABASE LINK dblink CONNECT TO 'remote_user' IDENTIFIED BY '********' USING (HOST '***.***.***.***', PORT '*****', DBNAME 'remote_db'); --host和port需要根据实际情况填写。
CREATE DATABASE LINK
-- 查询远程表。
local_db=> SELECT * FROM remote_tb@dblink ORDER BY f1;
 f1 | f2 |     f3     
----+----+------------
  0 | a  | {a0,b0,c0}
  1 | bb | {a1,b1,c1}
  2 | cc | {a2,b2,c2}
(3 rows)
-- 向远程表插入数据。
local_db=> INSERT INTO remote_tb@dblink VALUES (4,'d','{"a1","b2","c3"}');
INSERT 0 1
-- 更新远程表。
local_db=> UPDATE remote_tb@dblink SET f2 = 'aa' WHERE f1 = 0;
UPDATE 1
-- 删除远程表数据。
local_db=> DELETE remote_tb@dblink WHERE f1 = 1;
DELETE 1
-- 本地表JOIN远程表。
local_db=> SELECT * FROM remote_tb@dblink JOIN local_tb ON local_tb.f1 = remote_tb.f1@dblink;
 f1 | f2 |     f3     | f1 | f2 |     f3     
----+----+------------+----+----+------------
  2 | cc | {a2,b2,c2} |  2 | c  | {a2,b2,c2}
(1 row)
-- AGG函数。
local_db=> SELECT count(*) FROM remote_tb@dblink;
 count 
-------
     3
(1 row)
-- 访问远程函数。
local_db=> SELECT f@dblink(1,2);
 f 
---
 3
(1 row)
-- PLSQL_BODY内访问远程函数。
local_db=> CREATE OR REPLACE FUNCTION call_f(a in int, b in int)
RETURN INT AS
    tmp int;
BEGIN
    tmp := f@dblink(a, b);
    RETURN tmp;
END;
/
CREATE FUNCTION
local_db=> SELECT call_f(1, 2);
 call_f 
--------
      3
(1 row)
-- 创建DATABASE LINK对象的同义词。
local_db=> CREATE SYNONYM local_sy FOR remote_user.remote_tb@dblink;
CREATE SYNONYM
local_db=> SELECT * FROM local_sy ORDER BY f1;
 f1 | f2 |     f3     
----+----+------------
  0 | aa | {a0,b0,c0}
  2 | cc | {a2,b2,c2}
  4 | d  | {a1,b2,c3}
(3 rows)
-- 访问远程数据库的同义词。
local_db=> SELECT * FROM remote_sy@dblink ORDER BY f1;
 f1 | f2 |     f3     
----+----+------------
  0 | aa | {a0,b0,c0}
  2 | cc | {a2,b2,c2}
  4 | d  | {a1,b2,c3}
(3 rows)
-- DATABASE LINK支持部分Hint下推。
local_db=> EXPLAIN (VERBOSE, COSTS off) SELECT /*+ tablescan(remote_sy) */ * FROM remote_sy@dblink;
                                       QUERY PLAN                                        
-----------------------------------------------------------------------------------------
 Foreign Scan on "remote_user@dblink".remote_tb remote_sy
   Output: f1, f2, f3
   Exec Nodes: (dblink#nodegroup#0) datanode1
   Remote SQL: SELECT /*+  tablescan(remote_tb) */ f1, f2, f3 FROM remote_user.remote_tb
(4 rows)
-- 查看DATABASE LINK系统表gs_database_link。
local_db=> SELECT dlname,dlowner,options FROM gs_database_link;
 dlname | dlowner |                      options                    
--------+---------+----------------------------------------------------
 dblink |       0 | {host=***.***.***.***,port=*****,dbname=remote_db}
(1 row)
-- 查看DATABASE LINK系统视图gs_db_links。
local_db=> START TRANSACTION;
START TRANSACTION
local_db=> SELECT * FROM remote_sy@dblink ORDER BY f1;
 f1 | f2 |     f3     
----+----+------------
  0 | aa | {a0,b0,c0}
  2 | cc | {a2,b2,c2}
  4 | d  | {a1,b2,c3}
(3 rows)
local_db=> SELECT intransaction FROM gs_db_links;
 intransaction 
---------------
 t
(1 row)
local_db=> END;
COMMIT
-- 清理环境。
local_db=> \c postgres
gaussdb=# DROP DATABASE local_db;
DROP DATABASE
gaussdb=# DROP DATABASE remote_db;
DROP DATABASE
gaussdb=# DROP USER local_user;
DROP ROLE
gaussdb=# DROP USER remote_user;
DROP ROLE
```
