如果SELECT没有返回任何内容,MySQL拒绝INSERT INTO

时间:2014-11-19 01:02:54

标签: mysql sql subquery insert-update

我有一个表links,其中包含列id,url,url_hash和parent_id(还有更多与我的问题无关)。我的代码中有2个变量,$ url和$ parentUrl,它们可能引用links表中的现有行。所以我想将parent_id设置为其url与$ parentUrl匹配的第一个链接的id,或者将其设置为0,如果没有父级,则设置为null。

INSERT INTO `links` (`url`, `url_hash`, `parent_id`)
SELECT               $url,  MD5(url),   `id`
FROM `links`
WHERE `url` = $parentUrl
LIMIT 1

但是如果select语句返回0行,则会失败。我希望我的查询只是根据const值(url,url_hash)插入一个新行。

INSERT INTO `links` (`url`, `url_hash`, `parent_id`)
VALUES              ($url,  MD5(url), ((SELECT `id` FROM `links` WHERE `url`=$parentUrl LIMIT 1))

也试过这个,但这似乎失败了这个错误:

You can't specify target table 'links' for update in FROM clause

我这样做是为了避免使用两个查询的当前工作解决方案。甚至可以在一个查询中使用吗?

1 个答案:

答案 0 :(得分:1)

当你需要一排时 - 即使没有匹配 - 想想聚合。在你的情况下:

INSERT INTO `links` (`url`, `url_hash`, `parent_id`)
    SELECT $url, MD5($url), max(id)
    FROM (SELECT id
          FROM `links`
          WHERE `url` = $parentUrl
          LIMIT 1
         ) t;

这将生成一行。我不确定在这种情况下“第一”意味着什么。这将是一个任意行。您需要order by才能获得特定订单。

我也猜测表达式MD5(url)应该是MD5($url)

编辑:

并不是说它确实有很大的不同,但如果您只想引用$url一次:

INSERT INTO `links` (`url`, `url_hash`, `parent_id`)
    SELECT url, MD5(url), max(id)
    FROM (SELECT id, $url as url
          FROM `links`
          WHERE `url` = $parentUrl
          LIMIT 1
         ) t;