无法让 MySQL 在 INSERT 语句之前接受 NOT EXISTS
Posted
技术标签:
【中文标题】无法让 MySQL 在 INSERT 语句之前接受 NOT EXISTS【英文标题】:Can't get MySQL to accept NOT EXISTS before INSERT statement 【发布时间】:2014-05-02 23:54:35 【问题描述】:请注意,我无法通过在表上放置UNIQUE
约束来解决此问题。这是业务逻辑:如果要放置在某列中的值为 N,我们允许重复行。对于任何其他值,我们不会。
所以在检查传入参数的值并发现它不是我们允许欺骗的值之后,我这样做:
INSERT INTO userItems
VALUES ('0AA4DC20-5038-4A24-100F4DB16C6A', '1qubydk59mo059x4w2q99c', 'like', NULL)
WHERE NOT EXISTS (SELECT * FROM userItems WHERE userID = '0AA4DC20-5038-4A24-100F4DB16C6A' AND itemID = '1qubydk59mo059x4w2q99c' AND action = 'like')
这会导致:“检查与您的 mysql 服务器版本相对应的手册,以获取在 WHERE NOT EXISTS (SELECT * FROM user...
附近使用的正确语法
使用IF NOT EXISTS
也不起作用。也试过这个:
IF NOT EXISTS (SELECT * FROM userItems WHERE userID = '0AA4DC20-5038-4A24-100F4DB16C6A' AND itemID = '1qubydk59mo059x4w2q99c' AND action = 'like')
THEN
INSERT INTO userItems VALUES ('0AA4DC20-5038-4A24-100F4DB16C6A', '1qubydk59mo059x4w2q99c', 'like', NULL)
END IF
使用SELECT
(按照建议)代替VALUES
提供值不会插入任何内容,即使在独立语句中也是如此。这个:
INSERT INTO userItems (SELECT '541C3FFB-0711-4949-AD23-538B19F598D6', '10sz61gbuo2k11938s', 'like', NULL FROM userItems)
不做任何事情(没有插入行,即使表完全为空)。
但是VALUES
可以:
INSERT INTO userItems VALUES ('541C3FFB-0711-4949-AD23-538B19F598D6', '10sz61gbuo2k11938s', 'like', NULL)
【问题讨论】:
WHERE NOT EXISTS
应该是 select 语句的一部分,它不适用于 VALUES
。
【参考方案1】:
INSERT userItems
(SELECT
'0AA4DC20-5038-4A24-100F4DB16C6A',
'1qubydk59mo059x4w2q99c',
'like',
NULL
FROM
userItems
WHERE NOT EXISTS
(SELECT *
FROM userItems
WHERE userID = '0AA4DC20-5038-4A24-100F4DB16C6A' AND
itemID = '1qubydk59mo059x4w2q99c' AND
action = 'like'
)
);
【讨论】:
谢谢,但没有骰子。这就是我最初尝试的方法,但它也会引发语法错误:“...在 'IF NOT EXISTS (SELECT * FROM user..." 附近使用正确的语法” 谢谢,但还是不行:“查看与您的 MySQL 服务器版本相对应的手册,以了解在 'WHERE NOT EXISTS (SELECT * FROM userItems WHERE user..." 附近使用的正确语法。” 谢谢,终于成功了。但在语法上是多么愚蠢的解决方法。我想知道为什么没有人能解释 IF NOT EXISTS 构造的失败。 WOOPS:毕竟行不通。插入不做任何事情。事实上,即使插入语句本身也不会做任何事情。我会用详细信息更新我的问题。 @Oscar :那么,您使用VALUES
成功了吗?【参考方案2】:
由于“大部分唯一”规则,普通表约束不起作用,INSERT
不采用WHERE
子句,并且裸流控制是不好的语法,我会将逻辑包装在一个过程中.
DROP PROCEDURE IF EXISTS createUserItem;
DELIMITER $$
CREATE PROCEDURE createUserItem (
IN pUserID VARCHAR(35),
IN pItemID VARCHAR(35),
IN pAction VARCHAR(8),
IN pCol4 VARCHAR(4)
)
BEGIN
IF NOT EXISTS (
SELECT 'X'
FROM userItems
WHERE userID = pUserID
AND itemID = pItemID
AND action = pAction
) THEN
INSERT INTO userItems ()
VALUES (pUserID, pItemID, pAction, pCol4);
END IF;
END
$$
DELIMITER ;
那你就用CALL
mysql> CALL createUserItem('0AA4DC20-5038-4A24-100F4DB16C6A', '1qubydk59mo059x4w2q99c', 'like', NULL);
Query OK, 1 row affected (0.03 sec)
【讨论】:
感谢您的意见。只是好奇:我假设您将第二个示例称为“裸流控制”;为什么语法不好?还有:为什么它不起作用? 这是一种不好的语法,因为它返回了一个语法错误。这是因为IF
只能在存储过程或函数上下文中使用。以上是关于无法让 MySQL 在 INSERT 语句之前接受 NOT EXISTS的主要内容,如果未能解决你的问题,请参考以下文章
无法在准备好的 INSERT 语句中的 python mysql.connector 中使用 None (NULL) 值