我使用了以下查询:
select id from foo order by id DESC limit 1
返回上次使用的id
。
我在我的应用程序中有一些东西要加一个,如果它不是零。它工作正常。但我决定在sql而不是C#代码中执行此操作。但是当我这样做时:
SELECT IF(id = 0, 0, id + 1) as id from foo order by id DESC limit 1
但是我收到System.InvalidCastException
错误,令我惊讶的是,下面代码中打印的数据类型是int64。但它改变了吗?
这是c#代码:
public int GetLastID()
{
using (MySqlConnection con = Open())
{
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = "SELECT IF(id = 0, 0, id + 1) as id from foo order by id DESC limit 1";
cmd.Connection = con;
con.Open();
MySqlDataReader data = cmd.ExecuteReader();
if (!data.Read())
return 0;
System.Windows.Forms.MessageBox.Show(data["id"].GetType().ToString()); // output: int64
return (int)data["id"];
}
}
}
不要责怪我糟糕的mysql。我不太习惯。如果您知道更好的方法,请告诉我!
答案 0 :(得分:1)
我认为你想获得下一个id或最后一个id,但如果表为空,则函数返回零或一。这将为您提供最后插入的ID,而无需编写代码。它是一个内置功能:
select last_insert_id();
或者,如果您需要为特定的表执行此操作,而不是刚刚插入的最后一个表,那么这将为您提供最高的id + 1,如果表为空则只为1:
select ifnull(max(id),0) + 1 from mytable
这只是说 - 给我最大的id,但是如果它是null(表是空的),那么给我一个零。然后,无论哪两个回来,都加1。或者如果你想从零开始,那么做:
select ifnull(max(id) + 1, 0) from mytable
使用max(id)比通过降序orde选择第一行要好得多 - 效率更高。当然,使用自动增量更好,让数据库分配下一个id,如果你要做的是将id分配给你要插入的下一条记录。
答案 1 :(得分:1)
直接回答:不,别名不会改变您的数据类型,它会更改为查询返回的列显示的名称
答案 2 :(得分:1)
分配给列的别名( AS id
)不会更改数据类型。
表达式的数据类型是表达式的结果。
在MySQL中,整数加法运算(例如 id + 1
,其中id是整数类型)会产生BIGINT
。
此行为记录在(现在可用)MySQL参考手册中:https://dev.mysql.com/doc/refman/5.6/en/arithmetic-functions.html
摘录:
- 通常的算术运算符可用。结果根据以下规则确定:
对于
-
,+
和*
,如果两个操作数都是整数,则以BIGINT
(64位)精度计算结果。
因此,返回BIGINT
数据类型(64位整数)是预期的行为。
如果您的要求是返回一个32位整数,唯一的解决方法(我所知道的)就是创建一个用户定义的函数,例如
DELIMITER $$
CREATE FUNCTION udf_bigint_to_int(n BIGINT)
RETURNS INTEGER
BEGIN
RETURN n;
END$$
DELIMITER ;
作为一个演示,它的工作原理,以及作为行为的警告,传递的值大于32位整数可以支持的值,我们可以运行:
SELECT udf_bigint_to_int(9876543210+9)
返回32位整数的最大值:
udf_bigint_to_int(9876543210+9)
-------------------------------
2147483647
如果目的是从表中获取最大id
值,并向其中添加1,并将其作为32位整数返回,则在创建用户定义函数后,可以使用查询像这样:
SELECT udf_bigint_to_int( MAX(id) + ABS(SIGN( MAX(id) ))) AS id FROM foo