Answers:
如果您的DBMS对在执行插入操作时从哪个表中选择的表没有施加限制,请尝试:
INSERT INTO x_table(instance, user, item)
SELECT 919191, 123, 456
FROM dual
WHERE NOT EXISTS (SELECT * FROM x_table
WHERE user = 123
AND item = 456)
在这里,dual
是一个只有一行的表(最初在Oracle中找到,现在也在mysql中)。逻辑是SELECT语句将生成具有所需值的单行数据,但仅当尚未找到这些值时。
或者,查看MERGE语句。
dual
,则需要创建它。 CREATE TABLE dual ( dummy CHAR(1) DEFAULT 'x' NOT NULL CHECK (dummy = 'x') PRIMARY KEY ); INSERT INTO dual VALUES('x'); REVOKE ALL ON dual FROM PUBLIC; GRANT SELECT ON dual TO PUBLIC;
SELECT COUNT(*) FROM dual
始终获得1
,并且如果SELECT 'foo' FROM dual
您始终获得foo
。但是你不能SELECT * FROM dual
,你不能DESCRIBE dual
或类似的东西。我尚未检查,但我也不认为您可以撤消对的权限dual
。因此,值得指出的是,它可以按您期望的方式工作...除非不是,否则;)
INSERT IGNORE
当(用户,项目)具有唯一索引时,也可以使用它默默地忽略插入,而不是更新或插入行。
查询将如下所示:
INSERT IGNORE INTO x_table(instance, user, item) VALUES (919191, 123, 456)
您可以使用添加唯一索引CREATE UNIQUE INDEX user_item ON x_table (user, item)
。
你想要的是INSERT INTO table (...) SELECT ... WHERE ...
。从MySQL 5.6手册。
在您的情况下是:
INSERT INTO x_table (instance, user, item) SELECT 919191, 123, 456
WHERE (SELECT COUNT(*) FROM x_table WHERE user=123 AND item=456) = 0
或者,也许因为您没有使用任何复杂的逻辑来确定是否运行,INSERT
您可以仅对UNIQUE
这两列的组合设置一个键,然后使用INSERT IGNORE
。
ERROR 1064 (42000): 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 'where...
运行(运行5.6.34)
from dual
之前where
。
如果您添加(x_table.user,x_table.item)唯一的约束,则使用相同的用户和项目插入另一行将失败。
例如:
mysql> create table x_table ( instance integer primary key auto_increment, user integer, item integer, unique (user, item));
Query OK, 0 rows affected (0.00 sec)
mysql> insert into x_table (user, item) values (1,2),(3,4);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> insert into x_table (user, item) values (1,6);
Query OK, 1 row affected (0.00 sec)
mysql> insert into x_table (user, item) values (1,2);
ERROR 1062 (23000): Duplicate entry '1-2' for key 2
您可以使用以下解决方案来解决您的问题:
INSERT INTO x_table(instance, user, item)
SELECT 919191, 123, 456
FROM dual
WHERE 123 NOT IN (SELECT user FROM x_table)
dual
在这种情况下,是否需要事先创建?还是查询为单独使用查询而创建的某种特殊的“临时”表?