MySQL在重复键更新中插入多行... WHERE EXISTS(子查询)

时间:2019-04-13 19:53:27

标签: mysql on-duplicate-key

我想在表中插入多行的值。同样,在重复的情况下,查询必须能够更新那些行。但我也想检查用户是否有权使用子查询写入mytable。如何在一个命令中做到这一点?

不起作用的示例,因为MySQL INSERT syntax不支持WHERE子句:

INSERT INTO mytable (col1, col2, col3)
VALUES
(1, 2, 3),
(4, 5, 6),
(7, 8, 9)
ON DUPLICATE KEY UPDATE
col1=VALUES(col1), col2=VALUES(col2), col3=VALUES(col3)
WHERE EXISTS (subquery_to_verify_if_user_can_write_into_mytable); 

对于单行,它可能看起来像这样(工作示例,但只插入一行,而不是多行):

INSERT INTO mytable (col1, col2, col3) 
SELECT 1, 2, 3 FROM accesstable WHERE my_condition_to_check_if_user_can_write_into_mytable LIMIT 1
ON DUPLICATE KEY UPDATE
col1=VALUES(col1), col2=VALUES(col2), col3=VALUES(col3)

但是我想为多行插入值。 第一分钟PS Nice -1:))

最新编辑

这是一个丑陋的解决方案。用错误的dumb列创建具有所需值的表,并与通过询问用户访问权限而制成的伪造表联接起来:

INSERT INTO mytable (col1, col2, col3)
SELECT t1.c1, t1.c2, t1.c3
FROM (
    SELECT 1 c1, 2 c2, 3 c3, 0 dumb
    UNION SELECT 4, 5, 6, 0
    UNION SELECT 7, 8, 9, 0
    ) t1
JOIN (SELECT 0 dumb FROM accesstable WHERE user_id=114 LIMIT 1) t2
ON t1.dumb=t2.dumb
ON DUPLICATE KEY UPDATE
col1=VALUES(col1), col2=VALUES(col2), col3=VALUES(col3)

有人有更好的主意吗?我是数据库方面的初学者。我对最简单,最快的解决方案感兴趣。创建一个完整的伪造列并进行JOIN,在我看来,这是相当昂贵的操作,而且不太优雅。

改进的加入:感谢@Nick:

INSERT INTO mytable (col1, col2, col3)
SELECT t1.*
FROM ((
    SELECT 1 c1, 2 c2, 3 c3
    UNION SELECT 4, 5, 6
    UNION SELECT 7, 8, 9
    ) t1
CROSS JOIN (SELECT 1 FROM accesstable WHERE user_id=114 LIMIT 1) t2)
ON DUPLICATE KEY UPDATE
col1=VALUES(col1), col2=VALUES(col2), col3=VALUES(col3)

1 个答案:

答案 0 :(得分:1)

Personally, I would maintain access rights in the application layer and only execute the INSERT query if the user had those access rights. If you must do it solely in MySQL your last query is pretty much your only alternative, although it can be simplified (and made more efficient) by using a CROSS JOIN; this way you don't need the dummy column as all rows of the UNION table will be automatically joined to the single row from the access check (assuming it returns data). Note in my query I've added the id key column for demo purposes:

INSERT INTO mytable (id, col1, col2, col3)
SELECT t1.*
FROM ((
       SELECT 2 id, 1 col1, 2 col2, 3 col3
       UNION SELECT 1, 4, 5, 6
       UNION SELECT 3, 7, 8, 9
      ) t1
      CROSS JOIN (SELECT 1 FROM accesstable WHERE user_id=114 LIMIT 1) t2
     )
ON DUPLICATE KEY UPDATE
col1=VALUES(col1), col2=VALUES(col2), col3=VALUES(col3)

Demo on dbfiddle

将整个
链接为一个链接,但仍允许
内部使用其他链接