【问题标题】:How to solve single-row subquery returns more than one row如何解决单行子查询返回多行
【发布时间】:2016-02-16 22:26:27
【问题描述】:

我有一个员工表,其中包含薪水表。我想给所有现有员工增加 %10。我试图将所有员工的工资日期更新为特定日期,但我遇到了单行子查询的问题。

我的数据库是这样的:

CREATE TYPE TEMPORAL_VARCHAR AS OBJECT (
VALID_TIME_LOWER_BOUND DATE,
VALID_TIME_UPPER_BOUND DATE,
VALUE_PART VARCHAR2(50) );
CREATE TYPE TEMPORAL_NUMBER AS OBJECT (
VALID_TIME_LOWER_BOUND DATE,
VALID_TIME_UPPER_BOUND DATE,
VALUE_PART NUMBER );

CREATE TYPE NAME_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE ADDRESS_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE DEPARTMENT_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE MANAGER_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE SALARY_TYPE AS TABLE OF TEMPORAL_NUMBER;

CREATE TABLE EMPLOYEE (
SSN NUMBER primary key,
NAME NAME_TYPE,
ADDRESS ADDRESS_TYPE ,
BIRTH_DATE DATE,
MANAGER MANAGER_TYPE ,
DEPARTMENT DEPARTMENT_TYPE,
SALARY SALARY_TYPE
)
NESTED TABLE NAME STORE AS NAME_TABLE,
NESTED TABLE ADDRESS STORE AS ADDRESS_TABLE,
NESTED TABLE MANAGER STORE AS MANAGER_TABLE,
NESTED TABLE DEPARTMENT STORE AS DEPARTMENT_TABLE,
NESTED TABLE SALARY STORE AS SALARY_TABLE
;

如何解决这个问题?我试着这样做

UPDATE TABLE(
SELECT E.SALARY
FROM EMPLOYEE E
) SAL
SET SAL.VALID_TIME_UPPER_BOUND = '11.16.2015'
WHERE SAL.VALID_TIME_UPPER_BOUND = TO_DATE('12.31.9999','MM.DD.YYYY');

【问题讨论】:

  • 错误信息表示子查询返回多行。这意味着您的子查询对于它应该过滤的数据有一个有缺陷的 WHERE 子句。但是,您既没有发布带有子查询的 SELECT 语句,也没有发布任何示例日期。所以我不明白为什么你认为我们可以给你任何帮助。
  • 重复?这是同样的问题:stackoverflow.com/questions/3256433/…
  • UPDATE SALARY SET VALID_TIME_UPPER_BOUND = TO_DATE('11.16.2015', 'MM.DD.YYYY') WHERE VALID_UPPER_TIME_BOUND = TO_DATE('12.31.9999','MM.DD.YYYY') 是否按预期工作?
  • 我用了'alter session set NLS_DATE_FORMAT='MM.DD.YYYY';
  • 您正在通过使用表格类型进入一个受伤的世界。没有人真正使用这些东西 IRL - 我建议你立即放弃这个想法。

标签: sql oracle sql-update nested-table


【解决方案1】:

第一个可以重复

第二次看到sample这里

在您的代码中,您需要将where 条件带入选择中

UPDATE TABLE(
  SELECT E.SALARY
    FROM EMPLOYEE E 
      WHERE ssn in (SELECT ssn FROM EMPLOYEE e
   WHERE to_date('01.01.2015','mm.dd.yyyy')  in (
      SELECT VALID_TIME_UPPER_BOUND FROM TABLE(e.salary)
     ) 
   )
) SAL
SET SAL.VALID_TIME_UPPER_BOUND =  to_date('01.01.9999','mm.dd.yyyy')

test data

INSERT INTO EMPLOYEE(SSN, salary) values (1, SALARY_TYPE ());
INSERT INTO EMPLOYEE(SSN, salary) values (2, SALARY_TYPE ());
INSERT INTO EMPLOYEE(SSN, salary) values (3, SALARY_TYPE ());

INSERT INTO TABLE(SELECT salary FROM EMPLOYEE 
   WHERE ssn = 1)
   VALUES (to_date('01.01.2005','mm.dd.yyyy'), to_date('01.01.2015','mm.dd.yyyy'), 1);

INSERT INTO TABLE(SELECT salary FROM EMPLOYEE 
   WHERE ssn = 2)
   VALUES (to_date('02.02.2005','mm.dd.yyyy'), to_date('02.02.2015','mm.dd.yyyy'), 2);


INSERT INTO TABLE(SELECT salary FROM EMPLOYEE 
   WHERE ssn = 3)
   VALUES (to_date('03.03.2005','mm.dd.yyyy'), to_date('03.03.2015','mm.dd.yyyy'), 3);

p.s 你真的需要复杂性吗?

【讨论】:

    【解决方案2】:

    我用这样的迭代解决了我的问题

    BEGIN
      FOR employees IN (SELECT SSN FROM EMPLOYEE)
      LOOP
    UPDATE TABLE(
    SELECT E.SALARY
    FROM EMPLOYEE E
    WHERE E.SSN = employees.SSN
    ) SAL
    SET SAL.VALID_TIME_UPPER_BOUND = '11.16.2015'
    WHERE SAL.VALID_TIME_UPPER_BOUND = TO_DATE('12.31.9999','MM.DD.YYYY');
      END LOOP;
    END;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-16
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多