閱讀1004 返回首頁    go 阿裏雲 go 技術社區[雲棲]


PostgreSQL Oracle 兼容性 - synonym 匿名

標簽

PostgreSQL , 匿名 , synonym


背景

Oracle 的一個功能,支持對其他對象建立別名(匿名:synonym),它有什麼用呢?

比如某些業務係統中,代碼中寫死了要訪問的對象是在哪個用戶下的。當遷移時,如果遇到用戶名衝突,我們可能會選擇將對象同步到其他用戶下。那麼問題來了,程序也要改動,如果是很老的程序,估計找不到人來做這件事情。用synonym(匿名)可以很好的解決這個問題。

匿名語法如下

CREATE [ OR REPLACE ] [ PUBLIC ] SYNONYM  
   [ schema. ]synonym   
   FOR [ schema. ]object [ @ dblink ] ;  

https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_7001.htm

對於狀態可變的對象(例如表、序列)來說,匿名可以使用類似於指針引用的方法來實現。對於狀態不可變的對象(例如函數、視圖),匿名可以拷貝的方式來實現。實際上沒有永久不變的東西,函數內容,視圖的結構都是可能變化的。

下麵給出一些例子,在PostgreSQL中如何實現synonym(非內核實現)。

PostgreSQL synonym的方法

我們可以對多種對象建立匿名,方法各異。

1、表

代碼寫死了b.tbl123:

create table a.tbl(id int);  

通過視圖,

create view b.tbl123 as select * from a.tbl;  
  
這種簡單視圖,支持增刪改查,和直接使用a.tbl是一樣的。  
  
相當於建立了a.tbl的b.tbl123匿名。  

通過search_path,

如果對象名沒變,隻是在不同的schema下,使用search_path是最通用的方法:

set search_path=a,"$user",public;  
  
那麼會先訪問a這個schema下的對象。  

2、函數

代碼寫死了b.fun123:

create or replace function a.fun(int) returns int as $$  
....  
$$ language plpgsql strict;  

通過函數嵌套,

create or replace function b.fun123(int) returns int as $$  
select a.fun($1);  
$$ language sql strict;  

通過search_path,與1類似。

3、視圖

通過視圖,與1類似。

通過search_path

4、物化視圖

通過視圖,與1類似。

通過search_path,與1類似。

5、DBLINK

通過重定義一樣的dblink。

通過search_path,與1類似。

6、外部表

通過視圖,與1類似。

通過search_path,與1類似。

7、自定義類型

通過重定義一樣的類型。

通過search_path,與1類似。

8、序列

如果名字改變,可以通過覆蓋nextval,setval,currval來實現,例子

create or replace function nextval(name) returns int8 as $$  
declare  
  res int8;  
begin  
  if $1='目標seq對象名字' then  
    select pg_catalog.nextval('已存在seq對象'::regclass) into res;  
  else  
    select pg_catalog.nextval($1::regclass) into res;  
  end if;  
  return res;  
end;  
$$ language plpgsql strict;  
postgres=# select nextval('已存在seq對象');  
 nextval   
---------  
       1  
(1 row)  
  
postgres=# select nextval('目標seq對象名字');  
 nextval   
---------  
       2  
(1 row)  
  
postgres=# select nextval('已存在seq對象');  
 nextval   
---------  
       3  
(1 row)  

如果隻是search_path的問題,通過search_path解決,與1方法類似。

內核實現

內核實現當然是最好的,很早以前社區有提過這樣的PATCH,有興趣的同學可以考慮把它port到PG最新的版本來。

https://www.postgresql.org/message-id/440D446E.7040509@cybertec.at

使用了類似HOOK的方法。

最後更新:2017-10-28 23:34:06

  上一篇:go  PostgreSQL Oracle 兼容性 - order by INT(select位置 position)
  下一篇:go  PostgreSQL 和 Greenplum pgcrypto 加解密bytea處理差異