【问题标题】:SQL update statement with select from own table with multiple rows in oracleSQL更新语句,从自己的表中选择,在oracle中有多行
【发布时间】:2017-04-14 12:33:10
【问题描述】:

我想使用 WHERE 子句从表中选择多行,后记我想格式化日期并覆盖列。我创建了以下 SQL 语句:

UPDATE aufgabenliste.aufgabendefinition
SET tagesauswahl = (SELECT TO_CHAR(TO_DATE(CONCAT(tagesauswahl,'.2010'), 'DDD.MM.YYYY') , 'DDD.MM')  
                    FROM aufgabenliste.aufgabendefinition 
                    WHERE aufgabentyp = 4)
WHERE aufgabentyp = 4;

我收到一个错误,称为:

SQL Error: ORA-01427: single-row subquery returns more than one row

如何使用 oracle 对同一个表的多行进行 Select 更新?

【问题讨论】:

  • 将日期存储为 varchar2 不是一个好习惯。如果可以,最好添加日期类型的新列,根据当前列填充它,然后删除旧列。
  • 我同意你的观点,但它是一个现有的应用程序,其中包含一个包含大量数据的现有数据库,我只需要迁移这一行。所以没有其他方法可以使用这个 varchar2 列。
  • 请在您的表格中提供更新前后的一些示例数据,以便我们尝试看看您想要做什么。从表面上看,@JaydipJ 的答案看起来就是你想要做的,除了 tagesauswahl 列中的数据似乎是 DDD.MM 格式的字符串,所以你为什么要将它更新为这已经是任何人的猜测。这让我觉得您可能正在尝试将其更新到其他日期,但是如果没有示例输入/输出数据,这很难说。
  • 你说得对,但旧格式是例如 1.1,我想将其迁移到 001.01。当然 365.12 没有变化,但是对于单个字符的月份和日期,会有变化。

标签: sql oracle select


【解决方案1】:

错误SQL Error: ORA-01427: single-row subquery returns more than one row 表明您的内部子查询:

SELECT TO_CHAR(TO_DATE(CONCAT(tagesauswahl,'.2010'), 'DDD.MM.YYYY') , 'DDD.MM')  
                    FROM aufgabenliste.aufgabendefinition 
                    WHERE aufgabentyp = 4)

正在重新计算多行,并且您不能在不使用循环的情况下将多条记录分配给单个列,因此您的更新失败。更新的解决方案是将行数限制为 1,或者执行内部子查询结果为单行的操作。

您可以使用listaggmultiple rows 转换为由delimeter 分隔的single row,然后更新您的表格。见下文:

UPDATE aufgabenliste.aufgabendefinition
SET tagesauswahl = (SELECT listagg( TO_CHAR(TO_DATE(CONCAT(tagesauswahl,'.2010'), 'DDD.MM.YYYY') , 'DDD.MM'),',') within group (order by 1)  
                    FROM aufgabenliste.aufgabendefinition 
                    WHERE aufgabentyp = 4)
WHERE aufgabentyp = 4;

请注意,listagg 有一些限制,如果字符串长度增加了 varchar 的限制,它将失败。但是,如果您的行数有限,它会起作用。

【讨论】:

    【解决方案2】:
    UPDATE aufgabenliste.aufgabendefinition arow
    SET tagesauswahl = (SELECT TO_CHAR(TO_DATE(CONCAT(tagesauswahl,'.2010'), 'DDD.MM.YYYY') , 'DDD.MM')  
                        FROM aufgabenliste.aufgabendefinition 
                        WHERE ROWID = arow.ROWID)
    WHERE aufgabentyp = 4;
    

    您可以使用共同相关的子查询进行更新。
    arow 是获取更新的表的别名。在子查询中,我们指的是使用 Oracle 为每条记录提供的唯一 ROWID 更新的特定行。

    【讨论】:

      【解决方案3】:
      UPDATE aufgabenliste.aufgabendefinition SET tagesauswahl = TO_CHAR(TO_DATE(CONCAT(tagesauswahl,'.2010'), 'DDD.MM.YYYY') , 'DDD.MM') 
      WHERE aufgabentyp = 4;
      

      【讨论】:

        【解决方案4】:

        试试这个:在执行这个操作之前取回你的表。我非常确定我的解决方案,但不想冒险:)

        UPDATE aufgabenliste.aufgabendefinition
        SET tagesauswahl = TO_CHAR(TO_DATE(CONCAT(tagesauswahl,'.2010'), 'DDD.MM.YYYY') , 'DDD.MM')  
        WHERE aufgabentyp = 4;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-04-24
          • 2018-06-27
          • 2012-01-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多