2014-10-29 67 views

回答

2

檢查列名是否需要引用,方法是引用它們並將結果與​​原始值進行比較。

SELECT * from pg_attribute 
WHERE attname <> quote_ident(attname) 
     ; 

CREATE TABLE bad ("integer" integer not null primary key 
     , "where" TEXT NOT NULL 
     , "table" TEXT NOT NULL 
     , "as" TEXT NOT NULL 
     , "is" TEXT NOT NULL 
     , "primary" TEXT NOT NULL 
     , "references" TEXT NOT NULL 
     ); 

SELECT * from pg_attribute 
WHERE attname <> quote_ident(attname) 

DROP TABLE bad cascade; 

上面還會捕獲MixedCaseIdentifiers。要取消這些,請使用:

CREATE TABLE mixed ("Mixed" integer not null primary key); 

SELECT * from pg_attribute 
WHERE lower(attname) <> quote_ident(lower(attname)) 
     ; 

DROP TABLE mixed cascade; 

但是,這也會捕獲嵌入空格的標識符。爲了捕捉這些,在比較之前將其刪除:

CREATE TABLE spaced ("spa ced" integer not null primary key); 

SELECT * from pg_attribute 
WHERE lower(replace(attname, ' ' ,'')) 
    <> quote_ident(lower(replace(attname, ' ' ,''))) 
    ; 

相同的技巧,裹成一個SQL函數:

CREATE function check_needsquoting(str text) returns Boolean AS 
$func$ 
select lower(replace(str, ' ' ,'')) 
    <> quote_ident(lower(replace(str, ' ' ,''))) 
    ; 
$func$ LANGUAGE sql; 

SELECT check_needsquoting ('FooBar'); 
SELECT check_needsquoting ('where'); 
SELECT check_needsquoting ('create'); 

DROP function check_needsquoting(str text); 

結果:

CREATE FUNCTION 
check_needsquoting 
-------------------- 
f 
(1 row) 

check_needsquoting 
-------------------- 
t 
(1 row) 

check_needsquoting 
-------------------- 
t 
(1 row) 

DROP FUNCTION 

結合這個函數的結果來自通過@vyegorov提到功能)產量:

SELECT 
     kw.word, kw.catcode 
     , check_needsquoting(kw.word) AS needsquote 
from pg_get_keywords() kw 
ORDER BY kw.word 
     ; 

從而得出結論,只有catcode IN ('C', 'R')需要被引用。 注:pg_get_keywords()自Postgresql-8.4以來似乎可用。 (和quote_ident()至少 PostgreSQL相關7.2)


UPDATE:它出現在語法中使用的所有詞語需要檢測,不僅保留的:

CREATE function check_ifsyntaxword(str text) returns Boolean AS 
$func$ 
select EXISTS(
     select 1 
     from pg_get_keywords() kw 
     WHERE lower(kw.word) = lower(str) 
     ) 
    ; 
$func$ LANGUAGE sql; 
+0

事情是 - 標識符不僅僅是屬性,而是所有其他類型的對象。 – vyegorov 2014-10-29 13:26:35

+0

是的,的確如此,這只是第一次努力。 IIRC,在postgres源代碼中保留了一個保留字(關鍵字?)列表,我不知道它是否也作爲(僞)表發佈。會很整齊。注意:上面的片段捕獲「整數」;我希望它抓住「哪裏」,「作爲」,「是」等。更新:我只是檢查:它確實抓住了他們。 – wildplasser 2014-10-29 13:47:03

相關問題