我正在数据库中创建一个表,其中一列需要存储浮点数。但是,当我要求 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”下面的红色曲线会消失。从来没有。
如何在表格中创建具有浮点值的列?
这不是问题,而是:-
根据评论。 语法错误:-正在抱怨单词float(不是因为它是单词float)它说它不是:-
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 需要以下语法:-
所以你有:-
FOREIGN KEY
这是正确的,那么(username,
这是正确的(语法方面),并且由于列名称username
后面有一个逗号,因此需要后续列名称,所以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 表的所有行:-
第二个输出针对 f 表的所有行(具有 FKey 约束):-
第三个输出显示,有时需要小心,例如,10.234 和 '10.234' 不是相同的值,但可以直接或通过 LIKE 间接转换(例如):-
第四个输出实际上是 2 个查询连接(UNION),查询都使用 JOIN,但第二个输出对值进行 CASTS。因此,第一组(具有 P1 的行)忽略了由于 REAL v TEXT 值不相等而未满足比较的行,而第二组行(具有 P2)克服了差异:-