在 Oracle 中将子查询转换为单个值



我有一个地方列表。我需要在留言簿中为每个留言簿插入一张便条。

我有以下代码:

begin
  for rec in (
    SELECT p.place_id FROM Places p
    WHERE p.place_id NOT IN(
            SELECT DISTINCT v.place_id FROM Visits v
        )
  ) loop
    INSERT INTO Guestbook
    VALUES (
      rec.place_id,
      (
           SELECT MAX(person_id) INTO my_id
           FROM Persons
           WHERE name LIKE 'My Name'
           GROUP BY person_id;
      ),
      'My comment'
  );
  end loop;
end;

问题是插入不起作用,因为它将子查询视为列。但是即使我尝试在其上调用 MAX(),它也不会将其视为单个值。我需要该子查询只返回一个值,以便我可以将其插入到留言簿中

你有没有尝试过这样的事情。

SELECT (SELECT MAX(person_id) FROM Persons) INTO my_id
       FROM Persons
       WHERE name LIKE 'My Name'
       GROUP BY person_id;

您应该始终包含您收到的完整错误消息 - 在这种情况下,您在这一部分中有几个错误:

SELECT MAX(person_id) INTO my_id
       FROM Persons
       WHERE name LIKE 'My Name'
       GROUP BY person_id;
  • 分号 ';"' 标记 SQL 语句的末尾 - 由于您的语句在下一行继续,因此您必须将其删除
  • 如果要将 SQL
  • 语句的结果存储在 PL/SQL 变量中,则必须INTO my_id。由于它是更复杂的语句的一部分,因此在这里没有意义,必须将其删除。
  • MAX(person_id)GROUP BY person_id一起使用是没有意义的;我假设你想要GROUP BY name

最后,除非你想把它写成一个用于教育目的的循环,否则它可以(并且应该)重写为一个简单的 INSERT 语句:

INSERT INTO Guestbook(place_id, person_id, comment)
SELECT
  p.place_id,
  (
       SELECT MAX(person_id) 
       FROM Persons
       WHERE name LIKE 'My Name'
       GROUP BY name
  ),
  'My comment'
FROM Places p
WHERE p.place_id NOT IN (
   SELECT v.place_id FROM Visits v
);

这更短、更清晰、更高效。我还显式枚举了 INTO 子句中的列 - 这可确保将来将列添加到目标表中时代码仍然有效。

最新更新