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