PostgreSQL訪問SequoiaDB時,字段名稱的大小寫問題

在PG的官網文檔裏,關於字段名稱的大小寫有這麼一段描述:
https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html

因此,在pg裏面針對標識符(identifier)-- 主要是字段名稱 -- 的大小寫處理邏輯是:
-- 如果不將它用引號括起來,那麼pg會以“全部小寫字母”的形式保存這些標識符。
   所以說,foo和FOO和Foo都是沒有區別的,都等同於foo。
-- 如果對標識符加了引號,那麼就保留標識符內的大小寫來保存。
   因此,"foo"和"FOO"和"Foo"就是三個不同的字段名稱了;但是"foo"和foo還是一樣的,因爲都是小寫。

此外還有一點需要記住:SDB內的所有字段名都是區分大小寫的(不會自動轉成全小寫或者全大寫)!在SDB裏,foo和FOO和Foo在任何情況下都是三個不同的字段名,不管你是否加引號。

明白了上面兩點,就知道在pg連接SDB時如何處理大小寫問題了。下面舉幾個例子:

###  示例一

# sdb
sdb 'db.foo.createCL("bar")'
sdb 'db.foo.bar.insert({"id":1, "name":"wang tao"})'
sdb 'db.foo.bar.insert({"id":2, "name":"tang xun"})'
sdb 'db.foo.bar.find()'

# pg
create foreign table sdb_foo_bar (id int, name text) server sdb_server options ( collectionspace 'foo', collection 'bar') ;
create foreign table sdb_foo_bar1 (ID int, name text) server sdb_server options ( collectionspace 'foo', collection 'bar') ;
create foreign table sdb_foo_bar2 (id int, NAME text) server sdb_server options ( collectionspace 'foo', collection 'bar') ;
上面這三個外表雖然用了不同的大小寫形式,但由於沒有加引號實際上都是同一個結果,即兩個字段id和name。
並且,由於sdb中兩個id和name也都是小寫,所以這三個外表都可以訪問到foo.bar中的所有數據。

create foreign table sdb_foo_bar1_upper ("ID" int, name text) server sdb_server options ( collectionspace 'foo', collection 'bar') ;
create foreign table sdb_foo_bar2_upper (id int, "NAME" text) server sdb_server options ( collectionspace 'foo', collection 'bar') ;
上面這兩個外表,將大寫字母的字段名都用引號括了起來,因此就有問題了。它們分別對應下面的字段名:
  ID, name
  id, NAME
對於第一張外表,無法獲取foo.bar中的ID字段(因爲foo.bar中是id),而第二張外表則無法獲取foo.bar中的NAME字段(因爲foo.bar中是name)。


###  示例二

# sdb
sdb 'db.foo.createCL("bar_new")'
sdb 'db.foo.bar_new.insert({"ID":1, "name":"wang tao"})'
sdb 'db.foo.bar_new.insert({"ID":2, "name":"tang xun"})'
sdb 'db.foo.bar_new.find()'

# pg
create foreign table sdb_foo_bar_new (id int, name text) server sdb_server options ( collectionspace 'foo', collection 'bar_new') ;
create foreign table sdb_foo_bar_new1 (ID int, name text) server sdb_server options ( collectionspace 'foo', collection 'bar_new') ;
create foreign table sdb_foo_bar_new2 (id int, NAME text) server sdb_server options ( collectionspace 'foo', collection 'bar_new') ;
同理,由於字段沒有加引號所以上面三個外表實際上都是同一個結果:id和name。
但由於SDB的foo.bar_new中的字段名是大寫的ID,所以這三個表都無法獲取ID的數據。

create foreign table sdb_foo_bar_new1_upper ("ID" int, name text) server sdb_server options ( collectionspace 'foo', collection 'bar_new') ;
上面這張外表才正確地定義了兩個字段:ID和name,因此能正確獲取foo.bar_new中的數據。

需要注意的是:如果在SELECT語句裏想使用具體的字段名而不是用*,那麼必須是"ID"而不能是ID,因爲不帶引號的ID也會被轉換成小寫的id,從而成爲一個不存在的字段名!


總結:

如果用pg連接sdb,我認爲最佳的方法是:
1)在SDB裏的字段名稱儘量用全小寫。
2)在pg裏定義外表的時候,字段名不要使用引號;如果使用引號那要保證引號內是全小寫。
3)在pg裏執行SELECT的時候,字段名不要使用引號;如果使用引號那要保證引號內是全小寫。

如果SDB裏的字段名不是全小寫(全大寫,或者大小寫混合),那麼在pg裏使用的時候會比較麻煩:
1)在pg裏定義外表的時候,字段名必須使用引號!
2)在pg裏執行SELECT的時候,字段名必須使用引號!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章