首页 > 解决方案 > MySql 用 IF 语句创建记录

问题描述

SQL 查询论坛 20210309 我正在构建一个 Firebase Functions 应用程序,该应用程序与运行 MySQL 5.7 的 Google Cloud SQL 数据库通信。我试图从一个表中的一行中检索一个值,如果它存在(行或值),则在另一个表中插入一条记录。根据我在网上找到的一些示例,我的代码如下所示:

DECLARE meeting_link varchar(2048) DEFAULT ""; SELECT meeting_link from campaigns where id=2 INTO meeting_link; IF LENGTH(meeting_link) > 0 THEN INSERT INTO clicks (target_id, ip_address, user_agent) VALUES (38, "ip-address", "user-agent") END IF;

在我尝试过的所有不同版本中,我得到一个错误:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE meeting_link varchar(2048) DEFAULT ""; SELECT meeting_link from campaigns' at line 1

环顾四周,我发现帖子说除了存储过程我不能在任何东西中使用 DECLARE,但我可以使用局部变量(例如@ml),但我似乎也无法正常工作。

有人可以帮我解决我需要的 SQL 吗?仅当查询中的记录存在并将 meeting_link 值返回给我的调用程序时,我才需要创建记录。

标签: mysql

解决方案


请参阅此文档页面:

https://dev.mysql.com/doc/refman/8.0/en/sql-compound-statements.html

本节介绍 BEGIN ... END 复合语句的语法以及可用于存储程序主体的其他语句

这包括DECLARE也包括IF/THEN/ELSE/END结构。您不能在存储的例程之外使用那些。

您可以使用以下技巧代替存储的例程:

SELECT meeting_link from campaigns where id=2 INTO @meeting_link; 

INSERT INTO clicks (target_id, ip_address, user_agent) 
SELECT 38, 'ip-address', 'user-agent' FROM dual WHERE LENGTH(@meeting_link) > 0;

您可以使用@meeting_linkwhich is a user-defined variable,而不是声明的局部变量。

然后根据您的情况使用IF,而不是使用FROM dual WHERE ...。该dual表通常是一个伪表,实际上并不存在,但查询它会返回 1 行。WHERE但是,如果不满足子句中的条件,您可以将其设为零行。

因此 INSERT 将有条件地创建一行或零行。


回复您的评论:

如果您需要在单个 SQL 语句中完成此操作,那么一种选择是使该单个 SQL 语句CALL成为您在 MySQL 数据库中创建的过程。然后至少你可以像你想要的那样使用DECLARE和使用。IF

另一种选择是将上面显示的两个语句组合起来,如下所示:

INSERT INTO clicks (target_id, ip_address, user_agent) 
  SELECT 38, 'ip-address', 'user-agent' 
  FROM campaigns WHERE id=2 AND LENGTH(meeting_link) > 0;

这是有效的,因为即使您查询campaigns表,也不必选择该表的列。您可以改为选择常量值。子句中的条件WHERE将使其返回一行或零行。


推荐阅读