SQL - 将用户定义的变量添加到表(mysql)?
Posted
技术标签:
【中文标题】SQL - 将用户定义的变量添加到表(mysql)?【英文标题】:SQL - Adding user defined variables to table (mysql)? 【发布时间】:2015-08-28 21:31:44 【问题描述】:所以我有这个代码是存储过程的一部分:
SET @MID = 0;
SET @MX = 0;
SET @MY = 0;
SET @MT = 0;
SET @CSTAMP = '2014-6-06 08:03:19';
SELECT @MID=m.ID, @MX=m.x , @MY=m.y , @MT=m.timestamp FROM movement m
WHERE m.ID = cSID
AND m.timestamp = (SELECT MAX(T.timestamp)
FROM (SELECT mm.timestamp FROM movement mm WHERE mm.ID = cSID AND mm.timestamp <= @CSTAMP)AS T);
INSERT INTO DBTable(`ctimestamp`,`ID`,`x`,`y`,`mtimestamp`)
VALUES(ctstamp,@MID,@MX,@MY,@MT);
基本上,它会创建一些用户定义的变量,在查询中为它们分配值,并尝试将它们插入到名为DBTable
的表中,其中列ctimestamp
,ID
,x
,y
, mtimestamp
。问题是,当我在查询后看到DBTable
时,ID
、x
、y
和 mtimestamp
列都是空的(只有 0),只有 ctimestamp
填充了来自游标变量ctstamp
的值。
我不知道这里出了什么问题...我插入表格是不是错了?我不能以这种方式插入像@variable_name
这样的变量吗?
任何帮助将不胜感激,谢谢!
编辑
我刚刚想到,由于用户定义的变量是特定于会话的,这是否意味着我不能退出我的客户端并关闭计算机而让数据库服务器运行其余的查询?抱歉,这似乎是一个愚蠢的问题,但我对存储过程和 SQL 很陌生。
【问题讨论】:
如有疑问,请查看您的数据。具体来说,在插入查询之前选择所有变量。如果它们都为空,请查看您的选择查询并查看它返回的行数。 @DanBracuk 谢谢!我会试试的 是的,我会检查 cSID 是否真的返回任何东西。 【参考方案1】:在 SELECT 语句中,对用户定义变量的赋值使用(类似帕斯卡的)赋值运算符 (:=
) 而不仅仅是等号。
例如,这会将值'foo'
赋值给用户定义的变量:
SELECT @var := 'foo'
^
这与此大不相同:
SELECT @var = 'foo'
^
这不执行分配;它被评估为布尔表达式,相等比较返回的结果返回 0、1 或 NULL。
跟进
不需要所有这些用户定义的变量。您可以更高效地完成相同的结果(使用更少的 SQL 语句)
假设cSID
是一个过程变量,您可以通过以下方式完成等效结果:
SET @CSTAMP = '2014-6-06 08:03:19';
INSERT INTO DBTable(`ctimestamp`,`ID`,`x`,`y`,`mtimestamp`)
SELECT t.ctimestamp, m.ID, m.x, m.y, m.timestamp AS mtimestamp
FROM movement m
JOIN ( SELECT @CSTAMP + INTERVAL 0 DAY AS ctimestamp
, MAX(mm.timestamp) AS max_mm_timestamp
FROM movement mm
WHERE mm.ID = cSID
AND mm.timestamp <= @CSTAMP + INTERVAL 0 DAY
) t
ON m.ID = cSID
AND m.timestamp = t.max_mm_timestamp
ORDER BY 3,4
LIMIT 1
(用户定义的变量@CSTAMP 可以替换为过程变量。
DECLARE v_cstamp DATETIME DEFAULT '2014-06-06 08:03:19';
然后将对@CSTAMP
的引用替换为对过程变量的引用...v_cstamp
。
【讨论】:
哦,我明白了。所以基本上例如,@MID=m.ID
是关于我想要做什么的毫无意义的陈述
是的,SELECT 是有效的,因为 SELECT 'a'='b'
是一个有效的语句。但这不是你想要的。【参考方案2】:
最好在存储过程中使用普通变量。会话变量没有数据类型,如果您碰巧调用使用相同会话变量的其他过程,会话变量可能会在过程执行期间发生变化。
DECLARE v_mid int;
DECLARE v_mx int;
DECLARE v_my int;
DECLARE v_mt int;
DECLARE v_time datetime;
SELECT m.ID, m.x, m.y, m.timestamp INTO v_mid, v_mx, v_my, v_mt, v_time
FROM movement m
WHERE m.ID = cSID
AND m.timestamp = (
SELECT MAX(mm.timestamp)
FROM movement mm
WHERE mm.ID = cSID AND mm.timestamp <= v_time
);
INSERT INTO DBTable(`ctimestamp`,`ID`,`x`,`y`,`mtimestamp`)
VALUES(v_time,v_mid,v_mx,v_my,v_mt);
【讨论】:
我明白了……谢谢,我会记住这一点。所以在这样做时,除了变量的类型之外没有任何变化,对吧?我没有调用使用任何@var_name
的任何其他程序,所以这不会是我的错误吧?无论如何,我会改变它,看看它是怎么回事
查看 SELECT INTO 语法而不是 var = column 语法。 SQL Server / Sybase 使用 var = column 语法。 mysql 使用 SELECT INTO 语法。
可以在单个 INSERT ... SELECT
语句中完成等效操作,而不是单独的 SELECT
和 INSERT
语句,从而无需将值存储在过程变量中。
是的,INSERT ... SELECT 在这种情况下是更好的解决方案。只是回答如何在过程中使用变量的问题。以上是关于SQL - 将用户定义的变量添加到表(mysql)?的主要内容,如果未能解决你的问题,请参考以下文章