如何在SQLite中使表中的列具有浮点值?

问题描述 投票:0回答:1

我正在数据库中创建一个表,其中一列需要存储浮点数。但是,当我要求 SQLiteDatabase 创建表时,我不断收到浮点值名称下的错误。

我尝试在“创建表”语句末尾之外的某个位置声明浮动。

db.execSQL("CREATE TABLE " + teams_table_name + " (teamName varchar (50) primary key not null, foreign key (username) references " + users_table_name + " (username), averageBST float(3, 2), foreign key (pkmnOne) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnTwo) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnThree) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnFour) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnFive) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnSix) references " + pkmn_table_name + " (pkmnName));");

我尝试不声明浮点数中的位数以及小数点后有多少位。

db.execSQL("CREATE TABLE " + teams_table_name + " (teamName varchar (50) primary key not null, foreign key (username) references " + users_table_name + " (username), foreign key (pkmnOne) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnTwo) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnThree) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnFour) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnFive) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnSix) references " + pkmn_table_name + " (pkmnName), averageBST float);");

我尝试将“averageBST”全部设为小写字母。

db.execSQL("CREATE TABLE " + teams_table_name + " (teamName varchar (50) primary key not null, foreign key (username) references " + users_table_name + " (username), foreign key (pkmnOne) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnTwo) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnThree) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnFour) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnFive) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnSix) references " + pkmn_table_name + " (pkmnName), averagebasestattotal float);");

我尝试说averageBST不能为空,尽管我一开始就不会让这种情况发生。

db.execSQL("CREATE TABLE " + teams_table_name + " (teamName varchar (50) primary key not null, foreign key (username) references " + users_table_name + " (username), foreign key (pkmnOne) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnTwo) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnThree) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnFour) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnFive) references " + pkmn_table_name + " (pkmnName), foreign key (pkmnSix) references " + pkmn_table_name + " (pkmnName), averageBST float not null);");

当我尝试这些事情时,我希望“averageBST”下面的红色曲线会消失。从来没有。

java android sqlite floating-point create-table
1个回答
1
投票

如何在表格中创建具有浮点值的列?

这不是问题,而是:-

根据评论。 语法错误:-正在抱怨单词float(不是因为它是单词float)它说它不是:-

  1. 列名称列表的右括号,或
  2. averageBST
    列与另一个列名称分隔开的逗号。

我尝试不声明浮点数中的位数以及小数点后有多少位。

再次强调,averageBST AvErAgEbSt 或其他什么都不是问题,正如所解释的,它只是接近问题所在。大小写通常只与价值观真正相关。

我尝试说averageBST不能为空,尽管我一开始就不会让这种情况发生。

再次强调,

NOT NULL
约束是列定义的一部分,在外键约束中引用该列时不能使用。

修复很可能是:-

    db.execSQL("CREATE TABLE " + teams_table_name +
            "(" +
            "   teamName varchar (50) primary key not null, " +
            " averageBST REAL ," +
            /* ORIGINAL
            "foreign key (username) references " + users_table_name + " (username, " +
            "averageBST float(3, 2), " +*.
             */
            /*<<<<<<<<<< EXAMPLE OF CORRECT SYNTAX >>>>>>>>>>*/
            "foreign key (username) references " + pkmn_table_name + "(username,averageBST) ," +
            "foreign key (pkmnOne) references " + pkmn_table_name + " (pkmnName), " +
            "foreign key (pkmnTwo) references " + pkmn_table_name + " (pkmnName), " +
            "foreign key (pkmnThree) references " + pkmn_table_name + " (pkmnName), " +
            "foreign key (pkmnFour) references " + pkmn_table_name + " (pkmnName), " +
            "foreign key (pkmnFive) references " + pkmn_table_name + " (pkmnName), " +
            "foreign key (pkmnSix) references " + pkmn_table_name + " (pkmnName));");

可以看出,FOREIGN KEY 需要以下语法:-

FK

所以你有:-

  1. FOREIGN KEY 
    这是正确的,那么
  2. (username,
    这是正确的(语法方面),并且由于列名称
    username
    后面有一个逗号,因此需要后续列名称,所以
  3. averageBST
    但是

现在,语法期望使用

)
来表示列名称列表的末尾,或者如果要提供另一个列名称,则使用
,

而是对

 float(
进行编码。这是无效的列名称。

浮动不是问题 - 简要说明

至于使引用表中的列成为浮动。这取决于存储的数据。简而言之,SQLite 很灵活,在许多(大多数)情况下,任何类型的数据都可以存储在任何类型的列中(有一些例外)。请参阅https://www.sqlite.org/datatype3.html

但是,FLOAT (REAL) v TEXT 可能存在固有问题。以下 DEMO 显示了这一点(请参阅嵌入的注释)。以下可以使用 SQLite 工具运行,并且应该产生相同的结果。

/* Just in case not cleaned up */
DROP TABLE IF EXISTS f;
DROP TABLE IF EXISTS t;
/*Create the tables - note the funny!!! column type (will be NUMERIC affinity)*/
CREATE TABLE IF NOT EXISTS t (username TEXT PRIMARY KEY, other a_funny_column_type);
/* noting the column level FOREIGN KEY constraint */
CREATE TABLE IF NOT EXISTS f (id INTEGER PRIMARY KEY, f_data TEXT, f_username_reference REFERENCES t(username));
/* Add some data noting mathematical and text FP data (BEWARE)*/
INSERT INTO t VALUES
    (10.234,'A'),('10.123','B'),('Fred','C')
;
/* Add some referenced (in theory) data */
/* noting that again mathematical notation and text representation of FP values */
INSERT INTO f(f_data,f_username_reference) VALUES
    ('blah1','Fred')
    ,('blah2',10.234) /* mathematical FP notation*/
    ,('blah2A','10.234') /* text FP notation */
    ,('blah3',10.123)
    ,('blah3A','10.123')
;
/* OUTPUT 1 show the storage type of the username in the t table */
SELECT *, typeof(username) AS stored_type FROM t;
/* OUTPUT 2 show the storage type of the f_username_reference in the f table */
SELECT *, typeof(f_username_reference) AS stored_type FROM f;
/* show the equivalent of  join using a subquery noting that the info_2 column if null would not be joined due to the mismatch between text and real*/
SELECT 
    *,
    /* LIKE effectively casts values to text*/  
    (SELECT f.f_data||': '||f.f_username_reference||' TYPE is stored AS '||typeof(f.f_username_reference) FROM t WHERE t.username LIKE f.f_username_reference) AS info,
    /* if not cast */
    (SELECT f.f_data||': '||f.f_username_reference||' TYPE is stored AS '||typeof(f.f_username_reference) FROM t WHERE t.username = f.f_username_reference) AS info_2,
    (SELECT f.f_username_reference FROM t WHERE CAST(t.username AS FLOAT) = CAST(f.f_username_reference AS REAL)) AS when_cast
    
FROM f;
/* Showing that the type matters (TEXT v REAL) when using a JOIN*/
/* i.e. only 3 rows extracted when  using = BUT 6 rows when CASTing both values to the same*/
SELECT 'P1',* FROM t JOIN f ON t.username = f.f_username_reference
UNION ALL SELECT 'P2',* FROM t JOIN F ON CAST(t.username AS REAL) = CAST(f.f_username_reference AS REAL)
;

/* Cleanup */
DROP TABLE IF EXISTS f;
DROP TABLE IF EXISTS t; 

运行时获得以下输出:-

第一个输出针对 t 表的所有行:-

R1

  • 可以看出,SQLite 认为用户名列的所有值都存储为 TEXT 类型,即使第一行的值指定为数学符号 FP 值。

第二个输出针对 f 表的所有行(具有 FKey 约束):-

R2

  • 这里可以看出f_username_reference列的值不是同一存储类型。 ** 考虑到第一个结果,这可能有点令人困惑,但那是因为在第一个结果中,值必须用于索引。

第三个输出显示,有时需要小心,例如,10.234 和 '10.234' 不是相同的值,但可以直接或通过 LIKE 间接转换(例如):-

R3

第四个输出实际上是 2 个查询连接(UNION),查询都使用 JOIN,但第二个输出对值进行 CASTS。因此,第一组(具有 P1 的行)忽略了由于 REAL v TEXT 值不相等而未满足比较的行,而第二组行(具有 P2)克服了差异:-

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.