什么SQLite列名可以/不可以?

时间:2010-07-30 15:59:43

标签: sql sqlite keyword

SQLite的列名是否有任何规则?

  • 是否可以包含'/'等字符?
  • 可以是UTF-8吗?

5 个答案:

答案 0 :(得分:23)

http://www.sqlite.org/lang_keywords.html有完整列表!享受!

答案 1 :(得分:11)

  

它可以包含'/'这样的字符吗?

所有示例均来自在Linux上运行的SQlite 3.5.9。

如果用双引号括起列名,可以:

> CREATE TABLE test_forward ( /test_column INTEGER );
SQL error: near "/": syntax error
> CREATE TABLE test_forward ("/test_column" INTEGER );
> INSERT INTO test_forward("/test_column") VALUES (1);
> SELECT test_forward."/test_column" from test_forward;
1

那就是说,你可能不应该这样做

答案 2 :(得分:3)

以下答案基于SQLite源代码,主要依赖于文件parse.y(柠檬解析器的输入)。

TL; DR:

CREATE TABLE语句中列和表名称允许的字符串是

  • ' - 任意类型的转义字符串(甚至是关键字)
  • 标识符,表示
    • ```和" - 任意类型的转义字符串(甚至是关键字)
    • 下表中的一系列MSB=1 8位ASCII字符或带有1的7位ASCII字符,不构成关键字Valid identifier characters
  • 关键字INDEXED,因为它是非标准的
  • 关键字JOIN,原因我不知道。

SELECT语句中结果列允许的一系列字符是

  • 如上所述的字符串或标识符
  • 以上所有内容如果用作AS
  • 之后编写的列别名

现在探索过程本身

  1. 让我们看看CREATE TABLE

    的语法
    // The name of a column or table can be any of the following:
    //
    %type nm {Token}
    nm(A) ::= id(X).         {A = X;}
    nm(A) ::= STRING(X).     {A = X;}
    nm(A) ::= JOIN_KW(X).    {A = X;}
    
  2. 深入挖掘,我们发现

    // An IDENTIFIER can be a generic identifier, or one of several
    // keywords.  Any non-standard keyword can also be an identifier.
    //
    %type id {Token}
    id(A) ::= ID(X).         {A = X;}
    id(A) ::= INDEXED(X).    {A = X;}
    

    “通用标识符”听起来很陌生。然而,快速浏览tokenize.c会产生定义

    /*
    ** The sqlite3KeywordCode function looks up an identifier to determine if
    ** it is a keyword.  If it is a keyword, the token code of that keyword is 
    ** returned.  If the input is not a keyword, TK_ID is returned.
    */
    
    /*
    ** If X is a character that can be used in an identifier then
    ** IdChar(X) will be true.  Otherwise it is false.
    **
    ** For ASCII, any character with the high-order bit set is
    ** allowed in an identifier.  For 7-bit characters, 
    ** sqlite3IsIdChar[X] must be 1.
    **
    ** Ticket #1066.  the SQL standard does not allow '$' in the
    ** middle of identfiers.  But many SQL implementations do. 
    ** SQLite will allow '$' in identifiers for compatibility.
    ** But the feature is undocumented.
    */
    

    有关标识符字符的完整地图,请参阅tokenize.c

  3. 目前还不清楚result-column的可用名称是什么(即SELECT语句中指定的列名或别名)。 parse.y在这里再次有用。

    // An option "AS <id>" phrase that can follow one of the expressions that
    // define the result set, or one of the tables in the FROM clause.
    //
    %type as {Token}
    as(X) ::= AS nm(Y).    {X = Y;}
    as(X) ::= ids(Y).      {X = Y;}
    as(X) ::= .            {X.n = 0;}
    

答案 3 :(得分:2)

有效字段名称与有效表名称的规则相同。使用SQlite管理员进行了检查。

  1. 仅允许使用字母数字字符和下划线
  2. 字段名称必须以字母字符开头或加下划线
  3. 坚持这些并且不需要逃避,它可以避免将来的问题。

答案 4 :(得分:0)

除了放置&#34;非法&#34;双引号之间的标识符名称&#34;标识符#1&#34; [之前和之后]作品[识别#2]

例如

sqlite> create table a0.tt ([id#1] integer primary key, [id#2] text) without rowid;
sqlite> insert into tt values (1,'test for [x] id''s');
sqlite> select * from tt
   ...> ;
id#1|id#2
1|test for [x] id's