?
This document uses PHP Chinese website manual Release
SQL輸入由一系列命令commands組成。一條命令 由一系列tokens構(gòu)成,用一個(gè)分號(hào) (";")結(jié)尾。輸入流的終止也結(jié)束一條命令。哪些記號(hào)是合法 的取決于特定命令的語法。
記號(hào)可以是一個(gè)key word, 一個(gè) identifier, quoted identifier, literal(或常量), 或特殊的字符符號(hào)。 記號(hào)通常由空白分隔(空格/tab/換行符),但如果不存在混淆的時(shí)候也 可以不用(通常只是一個(gè)特殊字符與一些其它記號(hào)類型相連的時(shí)候)。
比如,下列命令是(語法上)合法的SQL輸入:
SELECT * FROM MY_TABLE; UPDATE MY_TABLE SET A = 5; INSERT INTO MY_TABLE VALUES (3, 'hi there');
這里是三條命令的序列,每條一行(盡管并不要求這么做;多條命令可以在 一行里,單條命令也可以合理地分裂成多行)。
另外,comments可以出現(xiàn)在SQL輸入中,它們不是標(biāo)記,但實(shí)際上它們等效于空白。
如果從哪些記號(hào)標(biāo)識(shí)命令、哪些是操作數(shù)或參數(shù)的角度考慮,SQL 語法并 不是非常一致。通常頭幾個(gè)記號(hào)是命令名子,因此上面的例子我們通常可以 說是一個(gè)"SELECT",一個(gè)"UPDATE",和一個(gè)"INSERT"命令。不過,UPDATE命令總是 要求一個(gè)SET在某個(gè)位置出現(xiàn),并且這個(gè)特定的INSERT還要求有一個(gè)VALUES才完整。 每條命令的準(zhǔn)確語法規(guī)則都在Part VI里描述。
像上面例子里的SELECT,UPDATE或VALUES這樣的記號(hào)都是關(guān)鍵子的例子,也就是那些 在SQL語言里有固定含義的單詞。記號(hào)MY_TABLE和A是標(biāo)識(shí)符的例子。根據(jù)使用它們的命令的不同, 它們標(biāo)識(shí)表、子段、或者其它數(shù)據(jù)庫對(duì)象的名子。因此,有時(shí)候只是 簡單地叫它們"names"。關(guān)鍵子和標(biāo)識(shí)符有著同樣的 詞法結(jié)構(gòu),意思是我們?cè)跊]有認(rèn)識(shí)這種語言之前是無法區(qū)分一個(gè) 記號(hào)是標(biāo)識(shí)符還是名子。你可以在Appendix C里找到一個(gè)關(guān)鍵子的完整列表。
SQL標(biāo)識(shí)符和關(guān)鍵子必須以一個(gè)字母(a-z以及帶變音符的字母和非拉丁字母)或下劃線(_)開頭, 隨后的字符可以是字母、下劃線、數(shù)字(0-9) 、美元符號(hào)($)。需要注意的是,根據(jù)SQL標(biāo)準(zhǔn),美元符號(hào) 不允許出現(xiàn)在標(biāo)識(shí)符中,因此使用美元符號(hào)將不易移植。SQL 標(biāo)準(zhǔn)不會(huì)定義 包含數(shù)字或者以下劃線開頭或結(jié)尾的關(guān)鍵子,因此按照這里的格式定義的 標(biāo)識(shí)符是安全的,不會(huì)和將來標(biāo)準(zhǔn)的擴(kuò)展特性沖突。
系統(tǒng)使用不超過NAMEDATALEN-1個(gè)字符作為標(biāo)識(shí)符; 你可以在命令中寫更長的名子,但它們會(huì)被截?cái)唷? NAMEDATALEN的缺省值是64,因此標(biāo)識(shí)符最大長度是63。 如果覺得這個(gè)限制有問題,那么你可以在 src/include/pg_config_manual.h里修改NAMEDATALEN來改變它。
標(biāo)識(shí)符和關(guān)鍵子名子都是大小寫無關(guān)的。因此
UPDATE MY_TABLE SET A = 5;
也可以等效地寫成
uPDaTE my_TabLE SeT a = 5;
一種好習(xí)慣是把關(guān)鍵子寫成大寫,而名子等用小寫:
UPDATE my_table SET a = 5;
還有第二種標(biāo)識(shí)符:delimited identifier或quoted identifier。它是通過在"中包圍 任意字符序列形成的。分隔標(biāo)識(shí)符總是一個(gè)標(biāo)識(shí)符,而不是關(guān)鍵子。因此, 你可以用"select"表示一個(gè)子段或者表的名子,而 一個(gè)沒有引號(hào)的"select"將被當(dāng)做一條命令的一部分, 因此如果把它當(dāng)做一個(gè)表名或者子段名使用的話就會(huì)產(chǎn)生一個(gè)分析錯(cuò)誤。 上面的例子可以用引號(hào)包圍的標(biāo)識(shí)符這么寫:
UPDATE "my_table" SET "a" = 5;
引號(hào)包圍的標(biāo)識(shí)符可以包含編碼不等于零的任意字符(要包含一個(gè)雙引號(hào), 可以寫兩個(gè)相連的雙引號(hào))。這樣我們就可以構(gòu)造那些原本是不允許的 表名或者子段名,比如那些包含空白或&符號(hào)的名子,但長度限制依舊。
一個(gè)帶引號(hào)的標(biāo)示符的變形允許帶有代碼點(diǎn)標(biāo)記的逃逸Unicode字符。 該變形以U&開始(大/小寫U后給有符號(hào))緊跟著打開的雙引號(hào), 之間沒有空格,例如 U&"foo"。 (需要注意的是,與&比較,這樣做會(huì)產(chǎn)生歧義。在操作符周圍加上空格來避免該問題) 在引號(hào)中,通過寫一個(gè)后面跟有四位十六進(jìn)制代碼點(diǎn)或跟有六位十六進(jìn)制代碼點(diǎn)加號(hào)的反斜杠,Unicode字符可以寫成逃逸格式。 例如,"data"可以寫成:
U&"d\0061t\+000061"
下例以西里爾字母寫俄文"slon"(象)。
U&"\0441\043B\043E\043D"
如果需要一個(gè)非反斜杠的不同的逃逸,可以通過在字符串之后使用UESCAPE語句來進(jìn)行聲明,如:
U&"d!0061t!+000061" UESCAPE '!'
逃逸字符可以是一個(gè)十六進(jìn)制數(shù)字以外的任何單個(gè)字符,加號(hào),一個(gè)單引號(hào),雙引號(hào),或一個(gè)空白字符。 需要注意的是,逃逸字符是寫在單引號(hào)中,而不是雙引號(hào)中。
字面上,為了將逃逸字符寫到標(biāo)示符中,可以將它寫兩次。
只有服務(wù)器字符集是UTF8時(shí),才會(huì)完全使用Unicode逃逸語法。 當(dāng)使用其他服務(wù)器字符集時(shí),只有在ASCII內(nèi)的(最多\u007F)代碼點(diǎn)可以被聲明。 4位和8位的數(shù)字形式可以被用來將UTF-16代理對(duì)聲明為大于U+FFFF的帶有代碼點(diǎn)的字符, 盡管這樣做是不必的(通過可用8位數(shù)字形式技術(shù))。 (當(dāng)服務(wù)器字符集是UTF8時(shí)使用代理對(duì),首先,它們結(jié)合成一個(gè)單一的代碼點(diǎn),然后再UTF-8編碼)
把一個(gè)標(biāo)識(shí)符用引號(hào)包圍起來同時(shí)也令它大小寫相關(guān),而沒有引號(hào)包圍起來的 名子總是轉(zhuǎn)成小寫。 比如,PostgreSQL認(rèn)為標(biāo)識(shí)符FOO,foo和"foo"是等價(jià)的, 但"Foo"但是"Foo"和"FOO"與上面三個(gè)以及彼此之間都是不同的。 PostgreSQL里對(duì)未加引號(hào)的名子總是轉(zhuǎn)換成小寫, 這和SQL標(biāo)準(zhǔn)是不兼容的,SQL標(biāo)準(zhǔn)要求未用引號(hào)包圍起來的名子總是 轉(zhuǎn)成大寫。因此根據(jù)標(biāo)準(zhǔn),foo等于 "FOO"但不等于"foo"。 如果你想編寫可移植的程序,那么我們建議你要么就總是用引號(hào) 包圍某個(gè)名子,要么就從來不引。
在PostgreSQL里有三種implicitly-typed constants:字符串、位串、數(shù)值。常量也可以聲明為明確的類型, 這樣就可以使用更準(zhǔn)確的表現(xiàn)形式以及可以通過系統(tǒng)更有效地處理。 這些將在后面的小節(jié)描述。
SQL里的一個(gè)字符串文本是用單引號(hào)(')包圍的任意字符序列, 比如'This is a string'。這種聲明字符串常量的 方法是SQL標(biāo)準(zhǔn)定義的。在這種類型的字符串常量里嵌入單引號(hào)的標(biāo)準(zhǔn)兼容的 做法是敲入兩個(gè)連續(xù)的單引號(hào),比如'Dianne''s horse'。 注意:兩個(gè)連續(xù)的單引號(hào)not是雙引號(hào) (")
兩個(gè)只是通過with at least one newline的空白分隔 的字符串常量會(huì)被連接在一起,并當(dāng)做它們是寫成一個(gè)常量處理。比如:
SELECT 'foo' 'bar';
等效于
SELECT 'foobar';
但是
SELECT 'foo' 'bar';
是非法的語法。這個(gè)怪異的行為是SQL聲明的, PostgreSQL遵循標(biāo)準(zhǔn)。
PostgreSQL還允許"escape"字符串中 的內(nèi)容,這是一個(gè)PostgreSQL對(duì)SQL標(biāo)準(zhǔn)的擴(kuò)展。逃逸字符串語法是通過 在字符串前寫字母E(大寫或者小寫)的方法聲明的。 比如 E'foo'。當(dāng)需要續(xù)行包含逃逸字符的字符串時(shí),僅需要在第一行的 開始引號(hào)前寫上E就可以了。 在逃逸字符串中,通過一個(gè)\開始C-結(jié)構(gòu)的反斜杠逃逸序列, 在該逃逸中,反斜杠與其之后字符的組合代表一個(gè)特殊的子節(jié)值,可參閱Table 4-1。
Table 4-1. 反斜杠逃逸序列
反斜杠逃逸序列 | 解釋 |
---|---|
\b | 退格 |
\f | 進(jìn)紙 |
\n | 換行 |
\r | 回車 |
\t | 水平制表符 |
\o, \oo, \ooo (o = 0 - 7) | 八進(jìn)制子節(jié)值 |
\xh, \xhh (h = 0 - 9, A - F) | 十六進(jìn)制值 |
\uxxxx, \Uxxxxxxxx (x = 0 - 9, A - F) | 16或32位十六進(jìn)制Unicode字符值 |
任何其它跟在反斜杠后面的字符都當(dāng)做文本看待。因此,要在字符串常量 里包含反斜杠,則寫兩個(gè)反斜杠(\\)。另外,PostgreSQL 允許用一個(gè)反斜杠來逃逸單引號(hào)(\'),不過,將來版本 的 PostgreSQL 將不允許這么用。所以最好堅(jiān)持使用符合標(biāo)準(zhǔn)的 ''.。
你有必要為你所創(chuàng)建的子節(jié)序列(特別是在使用八進(jìn)制或十六進(jìn)制逃逸時(shí))編寫有效的服務(wù)器字符集編碼字符。 當(dāng)服務(wù)器編碼是UTF-8時(shí),應(yīng)該使用Unicode逃逸或另一種Unicode逃逸語法(參閱Section 4.1.2.3)。 (后者通過寫出子節(jié)來處理UTF-8字符集,這樣做是很繁瑣的)。
只有服務(wù)器字符集是UTF8時(shí),才會(huì)完全使用Unicode逃逸語法。 當(dāng)使用其他服務(wù)器字符集時(shí),只有在ASCII內(nèi)的(最多\u007F)代碼點(diǎn)可以被聲明。 4位和8位的數(shù)字形式可以被用來將UTF-16代理對(duì)聲明為大于U+FFFF的帶有代碼點(diǎn)的字符, 盡管這樣做是不必的(通過可用8位數(shù)字形式技術(shù))。 (當(dāng)服務(wù)器字符集是UTF8時(shí)使用代理對(duì),首先,它們結(jié)合成一個(gè)單一的代碼點(diǎn),然后再UTF-8編碼)
Caution |
如果配置參數(shù) standard_conforming_strings 的值是 off,那么PostgreSQL 將能夠識(shí)別所有(無論有無前導(dǎo) E)字符串常量中的反斜杠逃逸,這是為了 與過去的歷史行為兼容。雖然standard_conforming_strings 目前的默認(rèn)值是off,但是在不久的將來會(huì)變成on 以與標(biāo)準(zhǔn)兼容。我們鼓勵(lì)在應(yīng)用中不使用反斜杠逃逸。如果你確實(shí)需要使用 反斜杠逃逸來表示特殊字符,那么請(qǐng)?jiān)谧址A壳凹由?tt class="LITERAL">E 以確保能夠被正確的處理。 除standard_conforming_strings之外, escape_string_warning和backslash_quote 置參數(shù)也影響字符串常量中反斜杠的處理。 |
編碼為零的字符不允許出現(xiàn)在字符串常量中。
一個(gè)帶引號(hào)的標(biāo)示符的變形允許帶有代碼點(diǎn)標(biāo)記的逃逸Unicode字符。 該變形以U&開始(大/小寫U后給有符號(hào))緊跟著打開的雙引號(hào), 之間沒有空格,例如 U&"foo"。 (需要注意的是,與&比較,這樣做會(huì)產(chǎn)生歧義。在操作符周圍加上空格來避免該問題) 在引號(hào)中,通過寫一個(gè)后面跟有四位十六進(jìn)制代碼點(diǎn)或跟有六位十六進(jìn)制代碼點(diǎn)加號(hào)的反斜杠,Unicode字符可以寫成逃逸格式。 例如,"data"可以寫成:
U&'d\0061t\+000061'
下例以西里爾字母寫俄文"slon"(象)。
U&'\0441\043B\043E\043D'
如果需要一個(gè)非反斜杠的不同的逃逸,可以通過在字符串之后使用UESCAPE語句來進(jìn)行聲明,如:
U&"d!0061t!+000061" UESCAPE '!'
逃逸字符可以是一個(gè)十六進(jìn)制數(shù)字以外的任何單個(gè)字符,加號(hào),一個(gè)單引號(hào),雙引號(hào),或一個(gè)空白字符。 需要注意的是,逃逸字符是寫在單引號(hào)中,而不是雙引號(hào)中。
只有服務(wù)器字符集是UTF8時(shí),才會(huì)完全使用Unicode逃逸語法。 當(dāng)使用其他服務(wù)器字符集時(shí),只有在ASCII內(nèi)的(最多\u007F)代碼點(diǎn)可以被聲明。 4位和8位的數(shù)字形式可以被用來將UTF-16代理對(duì)聲明為大于U+FFFF的帶有代碼點(diǎn)的字符, 盡管這樣做是不必的(通過可用8位數(shù)字形式技術(shù))。 (當(dāng)服務(wù)器字符集是UTF8時(shí)使用代理對(duì),首先,它們結(jié)合成一個(gè)單一的代碼點(diǎn),然后再UTF-8編碼)
同樣,字符串常量的Unicode逃逸語法只有當(dāng)配置參數(shù)standard_conforming_strings啟用時(shí)才能生效。 否則,該語法在解析SQL語法時(shí)給客戶端造成混淆,導(dǎo)致SQL注入或其他安全問題。 如果該參數(shù)設(shè)為OFF,該語法會(huì)帶著一條錯(cuò)誤信息一起唄注入。
字面上,為了將逃逸字符寫到標(biāo)示符中,可以將它寫兩次。
盡管聲明字符串常量的標(biāo)準(zhǔn)方法通常都很方便,但是如果字符串中包含 很多單引號(hào)或者反斜杠,那么理解字符串的內(nèi)容可能就會(huì)變得很苦澀, 因?yàn)槊總€(gè)單引號(hào)都要加倍。為了讓這種場合下的查詢更具可讀性, PostgreSQL允許另外一種稱作"美元符界定"的 字符串常量書寫辦法。一個(gè)通過美元符界定聲明的字符串常量由一個(gè)美元 符號(hào)($)、零個(gè)或多個(gè)字符組成的"tag"、 另一個(gè)美元符號(hào)、組成字符串常量的任意字符序列、一個(gè)美元符號(hào)、 與前面相同的記號(hào)、一個(gè)美元符號(hào)組成的。比如,下面是兩個(gè)不同的用美元 符界定的方法聲明"Dianne's horse"的例子:
$$Dianne's horse$$ $SomeTag$Dianne's horse$SomeTag$
請(qǐng)注意,在美元符界定的字符串里,單引號(hào)不允許逃逸。實(shí)際上, 在一個(gè)美元符界定的字符串里, 不允許逃逸任何字符:字符串內(nèi)容總是按照子面內(nèi)容書寫。反斜杠不是特殊的、 美元符自己也不是特殊的(除非它們和開標(biāo)簽的一部分匹配)。
我們可以通過在不同嵌套級(jí)別使用不同的"標(biāo)記"來實(shí)現(xiàn)嵌套。 最常見的是寫函數(shù)定義的時(shí)候。比如:
$function$ BEGIN RETURN ($1 ~ $q$[\t\r\n\v\\]$q$); END; $function$
這里,序列$q$[\t\r\n\v\\]$q$表示一個(gè)美元符界定的字符串 文本 [\t\r\n\v\\] ,在函數(shù)體被 PostgreSQL 執(zhí)行的時(shí)候,它將被識(shí)別出來。但是因?yàn)檫@個(gè)序列不匹配外層的界定符 $function$,所以只要考慮了外層字符串,它就只是常量 里面的普通字符而已。
如果有標(biāo)簽的話,一個(gè)美元符界定的字符串遵循和無引號(hào)包圍的標(biāo)識(shí)符相同 的規(guī)則,只是它不能包含美元符。標(biāo)簽是大小寫相關(guān)的,因此 $tag$String content$tag$是正確的,而 $TAG$String content$tag$則是錯(cuò)誤的。
一個(gè)后面緊跟著關(guān)鍵子或者標(biāo)識(shí)符的美元符界定字符串必須用空白與其后 的關(guān)鍵子或者標(biāo)識(shí)符隔開;否則美元符界定符將會(huì)被當(dāng)作標(biāo)識(shí)符的開 頭部分(否則,美元界定符會(huì)被看成其前面的標(biāo)識(shí)符)。
美元符界定不是SQL標(biāo)準(zhǔn),但是在寫復(fù)雜的字符串文本的時(shí)候,它通常 比標(biāo)準(zhǔn)的單引號(hào)語法更方便。尤其是在其它常量里表現(xiàn)字符串常量的時(shí)候 更有用。比如在過程函數(shù)定義里,如果用單引號(hào)語法,每個(gè)上面例子里的 每個(gè)反斜杠都必須寫四個(gè),它們?cè)谧鳛樽址谋痉治龅臅r(shí)候會(huì)減少為兩個(gè), 然后在函數(shù)執(zhí)行的時(shí)候在內(nèi)層字符串常量里會(huì)再次被解析為一個(gè)。
位串常量看起來很像在開引號(hào)前面有一個(gè)B(大寫或小寫) 的普通字符串(它們之間沒有空白),比如B'1001'。 位串常量里可以用的字符只有0和1。
另外,位串常量可以用十六進(jìn)制表示法聲明,方法是使用前綴X(大寫或者小寫), 比如X'1FF', 其中的每個(gè)十六進(jìn)制位等效于四個(gè)二進(jìn)制位。
兩種形式的位串常量都可以像普通字符串常量那樣跨行連續(xù)。位串常量 不能用美元符界定。
數(shù)值常量接受下列通用的形式:
digits digits.[digits][e[+-]digits] [digits].digits[e[+-]digits] digitse[+-]digits
這里的digits是一個(gè)或多個(gè)十進(jìn)制數(shù)字(0-9)。 如果有小數(shù)點(diǎn),那么至少有一位在小數(shù)點(diǎn)前面或后面。如果出現(xiàn)了指數(shù) 分隔符(e)那么至少有一個(gè)數(shù)字跟在它后面。 在常量里不能有空格或者其它字符。請(qǐng)注意任何前導(dǎo)正號(hào)或負(fù)號(hào)實(shí)際上 都不認(rèn)為是常量的一部分;它是施加于常量的一個(gè)操作符。
這里是一些合法的數(shù)值常量的例子:
42
3.5
4.
.001
5e2
1.925e-3
如果一個(gè)數(shù)值常量既不包含小數(shù)點(diǎn),也不包含指數(shù)操作符,那么如果它 的數(shù)值可以放在integer類型中(32位),則認(rèn)為它是integer類型; 如果它的數(shù)值可以放在bigint中(64位),則認(rèn)為它是bigint, 否則認(rèn)為它是numeric類型。包含小數(shù)點(diǎn)和/或指數(shù)操作符的常量總是 被認(rèn)為是numeric類型。
給一個(gè)數(shù)值常量賦予初始數(shù)據(jù)類型只是類型解析算法的開端。 在大多數(shù)情況下該常量會(huì)根據(jù)環(huán)境被自動(dòng)強(qiáng)制轉(zhuǎn)換成最合適的類型。 必要時(shí),你可以通過強(qiáng)制類型轉(zhuǎn)換把一個(gè)數(shù)值解析成特定的數(shù)據(jù)類型。 比如,你可以強(qiáng)制要求把一個(gè)數(shù)值當(dāng)作real(float4)類型來看,方法是這么寫:
REAL '1.23' -- 字符串風(fēng)格 1.23::REAL -- PostgreSQL(歷史的)風(fēng)格
這些實(shí)際上只是下面討論的通用轉(zhuǎn)換的特例。
arbitrary類型的常量都可以用下列表示法中的 任何一種來輸入:
type 'string' 'string'::type CAST ( 'string' AS type )
其中的'string'將會(huì)被轉(zhuǎn)換為type類型的常量。 如果不存在該常量所屬類型的歧義,那么可以省略明確的 類型轉(zhuǎn)換(比如,當(dāng)你把它直接賦予一個(gè)表子段的時(shí)候),這種情況下它 會(huì)自動(dòng)轉(zhuǎn)換。
其中的'string'可以用普通SQL表示法或者美元符界定來書寫。
我們還可以用函數(shù)風(fēng)格的語法來聲明類型轉(zhuǎn)換:
typename ( 'string' )
不過并非所有類型名都可以這樣使用;參閱Section 4.2.9獲取細(xì)節(jié)。
::, CAST()和函數(shù)調(diào)用語法 也可以用于聲明任意表達(dá)式的運(yùn)行時(shí)類型轉(zhuǎn)換(如節(jié)Section 4.2.9中討論的那樣)。但是為了避免語句歧義, type 'string'的形式 只能用于聲明一個(gè)子面常量的類型。type 'string'的另外一個(gè)限制是它不能用于 數(shù)組類型(要用::或CAST()聲明一個(gè)數(shù)組常量的類型)。
CAST()語法遵循SQL標(biāo)準(zhǔn)。type'string'語法是標(biāo)準(zhǔn)的一個(gè)推廣: SQL只是給少數(shù)幾種數(shù)據(jù)類型聲明了這個(gè)語法,但PostgreSQL允許將其用于所有類型。 ::和函數(shù)調(diào)用的語法 是PostgreSQL的歷史用法。
一個(gè)操作符是最多NAMEDATALEN-1(缺省63個(gè))個(gè)下列 字符的序列:
+?-?*?/?<?>?=?~?!?@?#?%?^?&?|?`??
不過,有幾個(gè)限制:--和/*不能出現(xiàn)在操作符 中的任何地方,因?yàn)樗鼈儠?huì)被當(dāng)做注釋開始對(duì)待。
多字符操作符不能以+或-, 結(jié)束, 除非其中至少還包含下列操作符之一:
~?!?@?#?%?^?&?|?`??
比如,@-是允許的操作符,但*-不是。這個(gè)限制允許 PostgreSQL在不要求記號(hào)之間有空白的情況下分析 SQL 兼容的查詢。
當(dāng)你使用非SQL標(biāo)準(zhǔn)的操作符的時(shí)候,你通常需要用空白分隔相鄰的 操作符以避免歧義。比如,如果你定義了一個(gè)叫@的左單目操作符, 那么你就不能寫成X*@Y; 而是要寫成X* @Y以確保PostgreSQL把它讀成兩個(gè)操作符, 而不是一個(gè)。
有些非字母數(shù)字字符有一些特殊含義,因此不能用做操作符。它們的用法細(xì)節(jié)可 以在相應(yīng)的描述語法元素的地方找到。本節(jié)只是描述它們的存在和概括一下 這些字符的目的。
美元符號(hào)($)后面跟著數(shù)字用于在一個(gè)函數(shù)體定義或者 預(yù)備語句中表示參數(shù)的位置。在其它環(huán)境里美元符號(hào)可能是一個(gè)標(biāo)識(shí)符名子 或者是一個(gè)美元符界定的字符串常量的一部分。
圓括弧(())用于分組和強(qiáng)制優(yōu)先級(jí)的時(shí)候含義與 平常一樣。有些場合里圓括弧是作為一個(gè)特定SQL命令的固定語法的 一部分要求的。
方括弧([])用于選取數(shù)組元素。參閱節(jié) Section 8.14 獲取更多信息。
Commas (,) are used in some syntactical constructs to separate the elements of a list. 逗號(hào)(,)在一些語法構(gòu)造里用于分隔一個(gè)列表的元素。
分號(hào)(;)結(jié)束一條SQL命令。它不能出現(xiàn)在 一條命令里的任何地方,除了在引號(hào)包圍的字符串常量或者標(biāo)識(shí)符中。
冒號(hào)(:)用于從數(shù)組中選取"slices" (參閱節(jié)Section 8.14)。在一些SQL語言里(比如嵌入SQL),冒號(hào)用于前綴變量名。
星號(hào)(*)在某些環(huán)境里表示一個(gè)表的全部子段或者 一個(gè)復(fù)合類型的值。在用作聚集函數(shù)的參數(shù)時(shí)還表示該聚集并不需要明確的參數(shù)。
句點(diǎn)(.)用在數(shù)字常量里,并用于分隔模式、表、子段名。
注釋是任意以雙劃線開頭并延伸到行尾的任意字符序列,比如:
-- This is a standard SQL comment
另外,還可以使用C-結(jié)構(gòu)的塊注釋:
/* multiline comment * with nesting: /* nested block comment */ */
這里注釋以/*開頭并擴(kuò)展到對(duì)應(yīng)的*/。 這些塊注釋可以嵌套,就像SQL標(biāo)準(zhǔn)里說的那樣(但和C不一樣), 因此我們可以注釋掉一大塊已經(jīng)包含塊注釋的代碼。
注釋在進(jìn)一步的語法分析之前被從輸入中流刪除并用空白代替。
Table 4-2顯示了PostgreSQL里面的操作符的優(yōu)先級(jí)和關(guān)聯(lián)性。 大多數(shù)操作符都有相同的優(yōu)先級(jí)并且都是左關(guān)聯(lián)的。 這種情況可能會(huì)有不那么直觀的行為; 比如,布爾操作符<和>與 布爾操作符<=和 >=之間有 著不同的優(yōu)先級(jí)。同樣,當(dāng)你把雙目和單目操作符組合使用的時(shí)候,有時(shí)候也需要 加圓括弧。比如
SELECT 5 ! - 6;
會(huì)被分析成
SELECT 5 ! (- 6);
因?yàn)榉治銎鞑恢?tt class="TOKEN">!被定義成了后綴操作符,而不是中綴操作符 (知道的時(shí)候只能是太晚了)。要在本例中獲得你需要的特性,你要寫成 SELECT (5 !) - 6; 這是我們?yōu)閿U(kuò)展性付出的代價(jià)。
Table 4-2. 操作符優(yōu)先級(jí)(遞減)
操作符/元素 | 關(guān)聯(lián)性 | 描述 |
---|---|---|
. | 左 | 表/子段名分隔符 |
:: | 左 | PostgreSQL特有的類型轉(zhuǎn)換操作符 |
[ ] | 左 | 數(shù)組元素選擇 |
- | 右 | 單目負(fù)號(hào) |
^ | 左 | 冪 |
*/% | 左 | 乘,除,模 |
+ - | 左 | 加,減 |
IS | ? | IS TRUE,IS FALSE,IS UNKNOWN,IS NULL |
ISNULL | ? | 測試是否為 NULL |
NOTNULL | ? | 測試是否不為 NULL |
(其他) | 左 | 所有其它的本地和用戶定義操作符 |
IN | ? | 集合成員 |
BETWEEN | ? | 范圍包含 |
OVERLAPS | ? | 時(shí)間間隔重疊 |
LIKEILIKESIMILAR | ? | 字符串模式匹配 |
<> | ? | 小于,大于 |
= | 右 | 等于,賦值 |
NOT | 右 | 邏輯非 |
AND | 左 | 邏輯與 |
OR | 左 | 邏輯或 |
請(qǐng)注意操作符優(yōu)先級(jí)也適用于和上面提到的同名的內(nèi)置操作符和用戶定義操作符。 比如,如果你為一些客戶數(shù)據(jù)類型定義一個(gè)"+"操作符,那么 它和內(nèi)置的"+"操作符有同樣的優(yōu)先級(jí),不管用它來干什么。
如果在OPERATOR語法里使用了模式修飾的操作符名,比如
SELECT 3 OPERATOR(pg_catalog.+) 4;
那么OPERATOR構(gòu)造就會(huì)有表Table 4-2 里面為"any other"操作符顯示的缺省優(yōu)先級(jí)。不管什么特定的操作符 出現(xiàn)在OPERATOR()里都是這樣。