PostgreSQL文法結構

來源:互聯網
上載者:User

標籤:

SQL 輸入由一系列命令組成。一條命令由一系列記號構成,用一個分號(";")結尾。輸入資料流的終止也結束一條命令。哪些記號是合法的取決於特定命令的文法。

記號可以是一個關鍵字標識符引號包圍的標識符文本(或常量)、特殊的字元符號。記號通常由空白分隔(空格/tab/分行符號),但如果不存在混淆的時候也可以不用(通常只是一個特殊字元與一些其它記號類型相連的時候)。

另外,在 SQL 輸入裡可以有注釋。它們不是記號,它們實際上等效於空白。

比如,下列命令是(文法上)合法的 SQL 輸入:

SELECT * FROM MY_TABLE;UPDATE MY_TABLE SET A = 5;INSERT INTO MY_TABLE VALUES (3, ‘hi there‘);

這裡是三條命令的序列,每條一行(儘管並不要求這麼做;多條命令可以在一行裡,單條命令也可以合理地分裂成多行)。

如果從哪些記號標識命令、哪些是運算元或參數的角度考慮,SQL 文法並不是強式一致性。通常頭幾個記號是命令名字,因此上面的例子我們通常可以說是一個"SELECT"、一個"UPDATE"、和一個"INSERT"命令。不過,UPDATE 命令總是要求一個 SET 在某個位置出現,並且這個特定的 INSERT 還要求有一個 VALUES 才完整。每條命令的準確文法規則都在 Part VI 裡描述。

4.1.1. 標識符和關鍵字

像上面例子裡的 SELECT, UPDATE, VALUES 這樣的記號都是關鍵字的例子,也就是那些在 SQL 語言裡有固定含義的單詞。記號 MY_TABLE 和 A 是標識符的例子。根據使用它們的命令的不同,它們標識表、欄位、或者其它資料庫物件的名字。因此,有時候只是簡單地叫它們"名字"。關鍵字和標識符有著同樣的詞法結構,意思是我們在沒有認識這種語言之前是無法區分一個記號是標識符還是名字。你可以在附錄C裡找到一個關鍵字的完整列表。

SQL 標識符和關鍵字必須以一個字母(a-z 以及帶變音符的字母和非拉丁字母)或底線(_)開頭,隨後的字元可以是字母、底線、數字(0-9)、貨幣符號($)。需要注意的是,根據 SQL 標準,貨幣符號不允許出現在標識符中,因此使用貨幣符號將不易移植。SQL 標準不會定義包含數字或者以底線開頭或結尾的關鍵字,因此按照這裡的格式定義的標識符是安全的,不會和將來標準的擴充特性衝突。

系統使用不超過 NAMEDATALEN-1 個字元作為標識符;你可以在命令中寫更長的名字,但它們會被截斷。NAMEDATALEN 的預設值是 64 ,因此標識符最大長度是 63 。如果覺得這個限制有問題,那麼你可以在 src/include/postgres_ext.h 裡修改 NAMEDATALEN 來改變它。

標識符和關鍵字名字都是大小寫無關的。因此

UPDATE MY_TABLE SET A = 5;

也可以等效地寫成

uPDaTE my_TabLE SeT a = 5;

一種好習慣是把關鍵字寫成大寫,而名字等用小寫:

UPDATE my_table SET a = 5;

還有第二種標識符:分隔識別碼引號包圍的標識符。它是通過在雙引號(")中包圍任一字元序列形成的。分隔識別碼總是一個標識符,而不是關鍵字。因此,你可以用"select"表示一個欄位或者表的名字,而一個沒有引號的 select 將被當做一條命令的一部分,因此如果把它當做一個表名或者欄位名使用的話就會產生一個分析錯誤。上面的例子可以用引號包圍的標識符這麼寫:

UPDATE "my_table" SET "a" = 5;

引號包圍的標識符可以包含編碼不等於零的任一字元(要包含一個雙引號,可以寫兩個相連的雙引號)。這樣我們就可以構造那些原本是不允許的表名或者欄位名,比如那些包含空白或與號(&)的名字。但長度限制依舊。

把一個標識符用引號包圍起來同時也令它大小寫相關,而沒有引號包圍起來的名字總是轉成小寫。比如,我們認為標識符 FOO, foo, "foo" 是等價的 PostgreSQL 名字,但 "Foo" 和 "FOO" 與上面三個以及它們之間都是不同的。PostgreSQL 裡對未加引號的名子總是轉換成小寫,這和 SQL 標準是不相容的,SQL 標準要求未用引號包圍起來的名字總是轉成大寫。因此根據標準,foo 等於 "FOO" 但不等於 "foo" 。如果你想編寫可移植的程式,那麼我們建議你要麼就總是用引號包圍某個名字,要麼就從來不引。

4.1.2. 常量

在 PostgreSQL 裡有三種隱含類型的常量:字串、位串、數值。常量也可以聲明為明確的類型,這樣就可以使用更準確的表現形式以及可以通過系統更有效地處理。這些將在後面的小節描述。

4.1.2.1. 字串常量

SQL 裡的一個字串文本是用單引號(‘)包圍的任一字元序列,比如 ‘This is a string‘ 。這種聲明字串常量的方法是 SQL 標準定義的。在這種類型的字串常量裡嵌入單引號的標準相容的做法是敲入兩個連續的單引號,比如 ‘Dianne‘‘s horse‘ 。注意:兩個連續的單引號不是雙引號(")。

兩個只是通過至少一個分行符號的空白分隔的字串常量會被串連在一起,併當做它們是寫成一個常量處理。比如:

SELECT ‘http://www.infocool.net‘‘bar‘;

等效於

SELECT ‘http://www.infocool.netbar‘;

SELECT ‘http://www.infocool.net‘      ‘bar‘;

是非法的文法。這個怪異的行為是 SQL 聲明的,PostgreSQL 遵循標準。

PostgreSQL 還允許 "逃逸"字串中的內容,這是一個 PostgreSQL 對 SQL 標準的擴充。逃逸字串文法是通過在字串前寫字母 E(大寫或者小寫)的方法聲明的。比如 E‘foo‘ 。當需要續行包含逃逸字元的字串時,僅需要在第一行的開始引號前寫上 E 就可以了。逃逸字串使用的是C-風格的反斜線(\)逃逸:\b(退格)、\f(進紙)、\n(換行)、\r(斷行符號)、\t(水平定位字元)。此外還支援 \digits 格式的逃逸字元(這裡的 digits 是一個八進位位元組數值),以及 \xhexdigits 格式的逃逸字元(這裡的hexdigits 代表十六進位位元組值)。你建立的位元組序列是否是伺服器的字元集編碼能接受的正確字元,是你自己的責任。任何其它跟在反斜線後面的字元都當做文本看待。因此,要在字串常量裡包含反斜線,則寫兩個反斜線(\\)。另外,PostgreSQL 允許用一個反斜線來逃逸單引號(\‘),不過,將來版本的 PostgreSQL 將不允許這麼用。所以最好堅持使用符合標準的 ‘‘ 。

警告

如果配置參數 standard_conforming_strings 的值是 off ,那麼 PostgreSQL 將能夠識別所有(無論有無前置 E)字串常量中的反斜線逃逸,這是為了與過去的曆史行為相容。雖然 standard_conforming_strings 目前的預設值是 off ,但是在不久的將來會變成 on 以與標準相容。我們鼓勵在應用中不使用反斜線逃逸。如果你確實需要使用反斜線逃逸來表示特殊字元,那麼請在字串常量前加上 E 以確保能夠被正確的處理。

除 standard_conforming_strings 之外,escape_string_warning 和 backslash_quote 配置參數也影響字串常量中反斜線的處理。

編碼為零的字元不允許出現在字串常量中。

4.1.2.2. 美元符界定字串常量

儘管聲明字串常量的標準方法通常都很方便,但是如果字串中包含很多單引號或者反斜線,那麼理解字串的內容可能就會變得很苦澀,因為每個單引號都要加倍。為了讓這種場合下的查詢更具可讀性,PostgreSQL 允許另外一種稱作"美元符界定"的字串常量書寫辦法。一個通過美元符界定聲明的字串常量由一個貨幣符號($)、零個或多個字元組成的"記號"、另一個貨幣符號、組成字串常量的任一字元序列、一個貨幣符號、與前面相同的記號、一個貨幣符號組成的。比如,下面是兩個不同的用美元符界定的方法聲明"Dianne‘s horse"的例子:

$$Dianne‘s horse$$$SomeTag$Dianne‘s horse$SomeTag$

請注意,在美元符界定的字串裡,單引號不允許逃逸。實際上,在一個美元符界定的字串裡,不允許逃逸任何字元:字串內容總是按照字面內容書寫。反斜線不是特殊的、美元符自己也不是特殊的(除非它們和開標籤的一部分匹配)。

我們可以通過在不同嵌套層級使用不同的"標記"來實現嵌套。最常見的是寫函數定義的時候。比如:

$function$BEGIN    RETURN ($1 ~ $q$[\t\r\n\v\\]$q$);END;$function$

這裡,序列 $q$[\t\r\n\v\\]$q$ 表示一個美元符界定的字串文本 [\t\r\n\v\\] ,在函數體被 PostgreSQL 執行的時候,它將被識別出來。但是因為這個序列不匹配外層的界定符 $function$ ,所以只要考慮了外層字串,它就只是常量裡面的一般字元而已。

如果有標籤的話,一個美元符界定的字串遵循和無引號包圍的標識符相同的規則,只是它不能包含美元符。標籤是大小寫相關的,因此 $tag$String content$tag$ 是正確的,而 $TAG$String content$tag$ 則是錯誤的。

一個後面緊跟著關鍵字或者標識符的美元符界定字串必須用空白與其後的關鍵字或者標識符隔開;否則美元符界定符將會被當作標識符的開頭部分([原文] otherwise the dollar quoting delimiter would be taken as part of the preceding identifier)。

美元符界定不是 SQL 標準,但是在寫複雜的字串文本的時候,它通常比標準的單引號文法更方便。尤其是在其它常量裡表現字串常量的時候更有用。比如在過程函數定義裡,如果用單引號文法,每個上面例子裡的每個反斜線都必須寫四個,它們在作為字串文本分析的時候會減少為兩個,然後在函數執行的時候在內層字串常量裡會再次被解析為一個。

4.1.2.3. 位串常量

位串常量看起來很像在開引號前面有一個 B(大寫或小寫)的一般字元串(它們之間沒有空白),比如 B‘1001‘ 。位串常量裡可以用的字元只有 0 和 1 。

另外,位串常量可以用十六進位標記法聲明,方法是使用首碼 X(大寫或者小寫),比如 X‘1FF‘ ,其中的每個十六進位位等效於四個二進位位。

兩種形式的位串常量都可以像一般字元串常量那樣跨行連續。位串常量不能用美元符界定。

4.1.2.4. 數值常量

數值常量接受下列通用的形式:

digitsdigits.[digits][e[+-]digits][digits].digits[e[+-]digits]digitse[+-]digits

這裡的 digits 是一個或多個十進位數字(0-9)。如果有小數點,那麼至少有一位在小數點前面或後面。如果出現了指數分隔字元(e)那麼至少有一個數字跟在它後面。在常量裡不能有空格或者其它字元。請注意任何前置正號或負號實際上都不認為是常量的一部分;它是施加於常量的一個操作符。

這裡是一些合法的數值常量的例子:

42
3.5
4.
.001
5e2
1.925e-3

如果一個數值常量既不包含小數點,也不包含指數操作符,那麼如果它的數值可以放在 integer 類型中(32位),則認為它是 integer 類型;如果它的數值可以放在 bigint 中(64位),則認為它是 bigint ,否則認為它是 numeric 類型。包含小數點和/或指數操作符的常量總是被認為是 numeric 類型。

給一個數值常量賦予初始資料類型只是類型解析演算法的開端。在大多數情況下該常量會根據環境被自動強制轉換成最合適的類型。必要時,你可以通過強制類型轉換把一個數值解析成特定的資料類型。比如,你可以強制要求把一個數值當作 real(float4) 類型來看,方法是這麼寫:

REAL ‘1.23‘  -- 字串風格1.23::REAL   -- PostgreSQL(曆史的)風格 

這些實際上只是下面討論的通用轉換的特例。

4.1.2.5. 其它類型的常量

任意類型的常量都可以用下列標記法中的任何一種來輸入:

typestring‘‘string‘::typeCAST ( ‘string‘ AS type )

其中的 ‘string‘ 將會被轉換為 type 類型的常量。如果不存在該常量所屬類型的歧義,那麼可以省略明確的類型轉換(比如,當你把它直接賦予一個表欄位的時候),這種情況下它會自動轉換。

其中的 ‘string‘ 可以用普通 SQL 標記法或者美元符界定來書寫。

我們還可以用函數風格的文法來宣告類型轉換:

typename ( ‘string‘ )

不過並非所有類型名都可以這樣使用;參閱節4.2.8擷取細節。

::, CAST() 和函數調用文法也可以用於聲明任意運算式的運行時類型轉換(如節4.2.8中討論的那樣)。但是 typestring‘ 的形式只能用於聲明一個字面常量的類型。typestring‘ 的另外一個限制是它不能用於數群組類型(要用 :: 或 CAST() 聲明一個常數陣列的類型)。

CAST() 文法遵循 SQL 標準。typestring‘ 文法是標準的一個推廣:SQL 只是給少數幾種資料類型聲明了這個文法,但 PostgreSQL 允許將其用於所有類型。:: 和函數調用的文法是 PostgreSQL 的曆史用法。

4.1.3. 操作符

一個操作符是最多 NAMEDATALEN-1 個(預設63個)下列字元的序列:

+ - * / < > = ~ ! @ # % ^ & | ` ?

不過,有幾個限制:
  • -- 和 /* 不能出現在操作符中的任何地方,因為它們會被當做注釋開始對待。

  • 多字元操作符不能以 + 或 - 結束,除非其中至少還包含下列操作符之一:

    ~ ! @ # % ^ & | ` ?

    比如,@- 是允許的操作符,但 *- 不是。這個限制允許 PostgreSQL 在不要求記號之間有空白的情況下分析 SQL 相容的查詢。

當你使用非 SQL 標準的操作符的時候,你通常需要用空白分隔相鄰的操作符以避免歧義。比如,如果你定義了一個叫 @ 的左單目操作符,那麼你就不能寫成 X*@Y ;而是要寫成 X* @Y 以確保 PostgreSQL 把它讀成兩個操作符,而不是一個。

4.1.4. 特殊字元

有些非字母數字字元有一些特殊含義,因此不能用做操作符。它們的用法細節可以在相應的描述文法元素的地方找到。本節只是描述它們的存在和概括一下這些字元的目的。

  • 貨幣符號($)後面跟著數字用於在一個函數體定義或者預備語句中表示參數的位置。在其它環境裡貨幣符號可能是一個標識符名字或者是一個美元符界定的字串常量的一部分。

  • 圓括弧(())用於分組和強制優先順序的時候含義與平常一樣。有些場合裡圓括弧是作為一個特定 SQL 命令的固定文法的一部分要求的。

  • 方括弧([])用於選取數組元素。參閱節8.10擷取更多資訊。

  • 逗號(,)在一些文法構造裡用於分隔一個列表的元素。

  • 分號(;)結束一條 SQL 命令。它不能出現在一條命令裡的任何地方,除了在引號包圍的字串常量或者標識符中。

  • 冒號(:)用於從數組中選取"片段"(參閱節8.10)。在一些 SQL 方言裡(比如嵌入 SQL),冒號用於首碼變數名。

  • 星號(*)在某些環境裡表示一個表的全部欄位或者一個複合類型的值。在用作聚集合函式的參數時還表示該聚集並不需要明確的參數。

  • 句點(.)用在數字常量裡,並用於分隔模式、表、欄位名。

4.1.5. 注釋

注釋是任意以雙劃線開頭並延伸到行尾的任一字元序列,比如:

-- 這是標準的 SQL92 注釋 

另外,還可以使用C-風格的塊注釋:

/* 多行注釋 * 可以嵌套: /* 被嵌套的塊注釋 */ */

這裡注釋以 /* 開頭並擴充到對應的 */ 。這些塊注釋可以嵌套,就像 SQL99 裡說的那樣(但和 C 不一樣),因此我們可以注釋掉一大塊已經包含塊注釋的代碼。

注釋在進一步的文法分析之前被從輸入中流刪除並用空白代替。

4.1.6. 詞法優先順序

表4-1顯示了 PostgreSQL 裡面的操作符的優先順序和關聯性。大多數操作符都有相同的優先順序並且都是左關聯的。這種情況可能會有不那麼直觀的行為;比如,布爾操作符 < 和 > 與布爾操作符 <= 和 >= 之間有著不同的優先順序。同樣,當你把雙目和單目操作符組合使用的時候,有時候也需要加圓括弧。比如

SELECT 5 ! - 6;

會被分析成

SELECT 5 ! (- 6);

因為分析器不知道 ! 被定義成了尾碼操作符,而不是中綴操作符(知道的時候只能是太晚了)。要在本例中獲得你需要的特性,你要寫成

SELECT (5 !) - 6;

這是我們為擴充性付出的代價。

表4-1. 操作符優先順序(遞減)

操作符/元素 關聯性 描述
. 表/欄位名分隔字元
:: PostgreSQL 特有的類型轉換操作符
[ ] 數組元素選擇
- 單目負號
^
* / % 乘,除,模
+ - 加,減
IS   IS TRUE, IS FALSE, IS UNKNOWN, IS NULL
ISNULL   測試是否為 NULL
NOTNULL   測試是否不為 NULL
(任何其它的) 所有其它的本地和使用者定義操作符
IN   集合成員
BETWEEN   範圍包含
OVERLAPS   時間間隔重疊
LIKE ILIKE SIMILAR   字串模式比對
< >   小於,大於
= 等於,賦值
NOT 邏輯非
AND 邏輯與
OR 邏輯或

請注意操作符優先順序也適用於和上面提到的同名的內建操作符和使用者定義操作符。比如,如果你為一些客戶資料類型定義一個"+"操作符,那麼它和內建的"+"操作符有同樣的優先順序,不管用它來幹什麼。

如果在 OPERATOR 文法裡使用了模式修飾的操作符名,比如

SELECT 3 OPERATOR(pg_catalog.+) 4;

那麼 OPERATOR 構造就會有表4-1裡面為"任何其它"操作符顯示的預設優先順序。不管什麼特定的操作符出現在 OPERATOR() 裡都是這樣。

更多資訊參考http://www.infocool.net

PostgreSQL文法結構

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.