我如何确保我的模式标识符(表名,列名...)中没有使用任何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