我如何確保我的模式標識符(表名,列名...)中沒有使用任何SQL and PostgreSQL's key words,即使是非保留字符?PostgreSQL:我如何檢查我沒有使用任何關鍵字?
有沒有辦法做到這一點與SQL查詢?
我如何確保我的模式標識符(表名,列名...)中沒有使用任何SQL and PostgreSQL's key words,即使是非保留字符?PostgreSQL:我如何檢查我沒有使用任何關鍵字?
有沒有辦法做到這一點與SQL查詢?
檢查列名是否需要引用,方法是引用它們並將結果與原始值進行比較。
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;
事情是 - 標識符不僅僅是屬性,而是所有其他類型的對象。 – vyegorov 2014-10-29 13:26:35
是的,的確如此,這只是第一次努力。 IIRC,在postgres源代碼中保留了一個保留字(關鍵字?)列表,我不知道它是否也作爲(僞)表發佈。會很整齊。注意:上面的片段捕獲「整數」;我希望它抓住「哪裏」,「作爲」,「是」等。更新:我只是檢查:它確實抓住了他們。 – wildplasser 2014-10-29 13:47:03