今天羣裏一個哥們發了個錯誤信息:
ERROR: cross-database references are not implemented: "public.test.id"
********** 錯誤 **********
ERROR: cross-database references are not implemented: "public.test.id"
SQL 狀態: 0A000
看到貼出的SQL語句時就發現他的錯誤了
comment on table public.test is '測試表';
comment on table public.test.id is '測試ID';
..
給字段加備註的時候應該是column,而不是table。修改完備註SQL就不會報錯。
報這種錯誤,得須要提醒一下,postgresql的體系結構認爲不一樣的數據庫是獨立的,因此並不支持跨庫查詢。並且執行一個查詢時,postgresql首先會檢查自身的dbname(通常鏈接的當前DB名,可不寫),而後是schema(由於一個DB裏可包含多個schema,默認鏈接是public),再最後纔是數據庫對象(table,view,function...)。
因此當出現cross-database錯誤時咱們就能夠認爲postgres認爲用戶作了一次非規範的跨庫操做了。
回過頭來想想,什麼狀況下會報這種錯誤呢,我整理了一下,有如下這麼幾種狀況:
測試環境:
postgresql 9.1.2
postgres=# \l
資料庫列表
名稱 | 擁有者 | 字元編碼 | Collate | Ctype | 存取權限
-----------+----------+----------+---------+-------+-----------------------
d_kenyon | postgres | UTF8 | C | C |
postgres | postgres | UTF8 | C | C |
template0 | postgres | UTF8 | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
(4 行記錄)
postgres=# \d
關聯列表
架構模式 | 名稱 | 型別 | 擁有者
----------+----------------+--------+----------
public | pgweb | 資料表 | postgres
public | t_kenyon | 資料表 | postgres
public | tbl_order_item | 資料表 | postgres
public | tbl_orders | 資料表 | postgres
public | tbl_product | 資料表 | postgres
(5 行記錄)
postgres=# select current_user;
current_user
--------------
postgres
(1 行記錄)
postgres=# \c d_kenyon
You are now connected to database "d_kenyon" as user "postgres".
d_kenyon=# \d
關聯列表
架構模式 | 名稱 | 型別 | 擁有者
----------+-------+--------+----------
public | test | 資料表 | postgres
public | test2 | 資料表 | postgres
(2 行記錄)
1.真正地作了一次跨庫查詢
d_kenyon=# select *from postgres.public.t_kenyon limit 1;
ERROR: cross-database references are not implemented: "postgres.public.t_kenyon
"
第1行select *from postgres.public.t_kenyon limit 1;
^
d_kenyon=#
2.沒有作跨庫查詢,可是pg誤認爲你作了一次跨庫操做
postgres=# \d
關聯列表
架構模式 | 名稱 | 型別 | 擁有者
----------+----------------+--------+----------
public | pgweb | 資料表 | postgres
public | t_kenyon | 資料表 | postgres
public | tbl_order_item | 資料表 | postgres
public | tbl_orders | 資料表 | postgres
public | tbl_product | 資料表 | postgres
(5 行記錄)
postgres=# \d t_kenyon
資料表 "public.t_kenyon"
欄位 | 型別 | 修飾詞
--------+---------+--------
id | integer |
t_name | text |
postgres=# select * from public.t_kenyon limit 1;
id | t_name
----+--------
1 | kenyon
(1 行記錄)
postgres=# select * from public.t_kenyon.id limit 1;
ERROR: cross-database references are not implemented: "public.t_kenyon.id"
第1行select * from public.t_kenyon.id limit 1;
postgres=# select * from public.t_kenyon.22 limit 1;
ERROR: syntax error at or near ".22"
第1行select * from public.t_kenyon.22 limit 1;
^
postgres=# select * from public.t_kenyon.x22 limit 1;
ERROR: cross-database references are not implemented: "public.t_kenyon.x22"
第1行select * from public.t_kenyon.x22 limit 1;
第二種場景裏面還有多種方式會觸發,好比最開始提到的comment,insert...select...也有可能,第二種場景裏有一個頗有意思的發現,當最後一個實心點後面跟的是數字時並不報跨庫錯誤,而是語法錯誤。
擴展: 1.schema是 postgresql裏一個相對特別的數據庫對象,能夠簡單將理解成是一個容器,相似oracle的一個namespace,可是更靈活,可對schema授相應的用戶權限來控制; 2.除此以外,能夠將DB中的數據按相應的功能作水平切分,存放到不一樣的schema裏面; 3.不一樣的用戶能夠設置不一樣的默認schema,可參考search_path這個變量; 4.目前版本JDBC鏈接postgresql時須要先鏈接上來,而後執行set search_path to xxx,否則可能取不到特定schema下的數據。