我遇到此错误是在多表关联update的

UPDATE  EDASYS.CELL_COMPONENT_T A
SET A.ARRAY_GLASS_ID = (SELECT M.ARRAY_GLASS_ID FROM EDASYS.CELL_ARRAY_CF_MAPPING_T M WHERE M.CF_GLASS_ID = A.COMPONENT_ID AND  rownum < 2)
WHERE  EXISTS (SELECT 1 FROM EDASYS.CELL_ARRAY_CF_MAPPING_T M WHERE  1=1 AND A.STEP_ID = 'L1110' AND A.COMPONENT_START_TIME >= TO_DATE('2018-06-03','yyyy-mm-dd')
AND A.COMPONENT_START_TIME <= TO_DATE('2018-06-27','yyyy-mm-dd')
AND A.COMPONENT_ID LIKE 'C%')

在关联M表进行更新A表的一个字段的时候,总是会报单行子查询返回多个行。一开始百思不得其解。

-----------------------------------------------------2018/09/09 update-------------------------------------------

今天在update CELL2_CHIP_T的cf_chip_id & chip_no时又遇到同样的问题,难道是上次没有理解这个问题?我又仔细看了上次的笔记,结论就是   对上次的解决方案理解不透彻。

既然能意识到子查询关联的字段有多笔记录导致的。但是无法解决,是因为我这次做的update是在在同一张表上做操作。思维定式上认为两张表关联update时才会用此种解决方案。其实为啥 把同一张表 起两个别名 难道不一样?请看如下sql

UPDATE EDASYS.CELL2_CHIP_T A SET A.ITEM29 =
(SELECT (B.CF_GLASS_ID || '02') FROM EDASYS.CELL2_CHIP_T B WHERE
A.CHIP_ID = B.CHIP_ID
AND B.CHIP_START_TIME >= TO_DATE('2018-09-09 00:00','yyyy-mm-dd HH24:MI:SS')
AND B.CHIP_START_TIME <= TO_DATE('2018-09-09 00:10','yyyy-mm-dd HH24:MI:SS')
AND  substr(B.PRODUCT_ID,3,3) = '495' AND substr(B.CHIP_ID,11,2) = '01' AND B.CF_GLASS_ID IS NOT NULL
AND  rownum < 2)
WHERE
EXISTS(SELECT 1 FROM EDASYS.CELL2_CHIP_T B where
1=1 AND A.CHIP_START_TIME >= TO_DATE('2018-09-09 00:00','yyyy-mm-dd HH24:MI:SS')
AND A.CHIP_START_TIME <= TO_DATE('2018-09-09 00:10','yyyy-mm-dd HH24:MI:SS')
AND  substr(A.PRODUCT_ID,3,3) = '495' AND substr(A.CHIP_ID,11,2) = '01' AND A.CF_GLASS_ID IS NOT NULL )

请注意斜体的部分,是同一张表。用这种方法update完全可以完成任务,在同一张表中,根据一个字段update另外一个字段。

1、在子查询中增加 AND  rownum < 2 --拿到子查询中的一笔记录?接下来才是关键 如何和两外一张表把这笔唯一记录关联起来

2、将外层查询修改为 where exits(SELECT 1 FROM table_B where A.表的条件 ) --加租的这句话就是从B表中拿一条满足A表查询条件的数据去update.

为什么要增加exists?

如果不加exists  ,没有匹配上的字段都会置为空值;所以必须要加 where exists   限制条件。 
比如 cell_component_t 中存在一条 array_glass_id ='A18A3211CG' 的记录,而 cell_array-cf_mapping_t没有, 
不加  where exists   限制, cell_component_t 中array_glass_id ='A18A3211CG'记录的array_glass_id 字段将被置为空值,原来的值会被清除。 

虽然此种方案可以完成任务,但是极其繁琐,需要每一模修改一次SQL。

于是请教了一下老大,他用了一个及其巧妙的SQL:

--495
update cell2_chip_t set item30= trim(to_char( trunc((chip_no+1)/2) * 4-1 - chip_no,'00')) ,item29= trim(cf_glass_id) || trim(to_char( trunc((chip_no+1)/2) * 4-1 - chip_no,'00')) where 1=1 and record_index >= 201712010000000000 and  record_index < 201712020000000000 and product_id like'%495%' and (substr(item29,1,1) <>'C' or item29  is null);commit;
--315
update cell2_chip_t set item30= trim(to_char( 6*(trunc((chip_no+2)/3)-1)+4 - chip_no,'00')),item29=  trim(cf_glass_id) || trim(to_char( 6*(trunc((chip_no+2)/3)-1)+4 - chip_no,'00')) where 1=1 and record_index >= 201808010000000000 and  record_index < 201808020000000000 and product_id like'%315%' and (substr(item29,1,1) <>'C' or item29  is null);commit;
--575
update cell2_chip_t set item30= trim(to_char( 6*(trunc((chip_no+2)/3)-1)+4 - chip_no,'00')),item29=  trim(cf_glass_id) || trim(to_char( 6*(trunc((chip_no+2)/3)-1)+4 - chip_no,'00')) where 1=1 and record_index >= 201802010000000000 and  record_index < 201802020000000000 and (product_id like'%575%' or product_id like'%315%') and (substr(item29,1,1) <>'C' or item29  is null);commit;
--695
--not panel 5
update cell2_chip_t set item30= trim(to_char( 6*(trunc((chip_no+2)/3)-1)+4 - chip_no,'00')),item29=  trim(cf_glass_id) || trim(to_char( 6*(trunc((chip_no+2)/3)-1)+4 - chip_no,'00')) where 1=1 and record_index >= 201807010000000000 and  record_index < 201807020000000000 and (product_id like'%695%') and chip_no<'05' and (substr(item29,1,1) <>'C' or item29  is null);commit;
-- is Panel 5
update cell2_chip_t set item30= '05',item29=  trim(cf_glass_id) || '05' where 1=1 and record_index >= 201807010000000000 and  record_index < 201809080000000000 and (product_id like'%695%') and AND chip_no = '05' and (substr(item29,1,1) <>'C' or item29  is null);commit;

真的是事半功倍。

此外还要注意如果在子查询中增加查询条件会提高效率。

SELECT * FROM (
SELECT COUNT(1),ARRAY_GLASS_ID  FROM EDASYS.CELL_ARRAY_CF_MAPPING_T M GROUP BY ARRAY_GLASS_ID ORDER BY COUNT(1) DESC)

看到这个结果我知道了,因为EDASYS.CELL_ARRAY_CF_MAPPING_T有502条为-1的记录。就是子查询关联的字段有多笔记录导致的。

看前辈我是这样解决的:

UPDATE  EDASYS.CELL_COMPONENT_T A  
SET A.ARRAY_GLASS_ID = (SELECT M.ARRAY_GLASS_ID FROM EDASYS.CELL_ARRAY_CF_MAPPING_T M WHERE M.CF_GLASS_ID = A.COMPONENT_ID AND  rownum < 2) 
WHERE  EXISTS (SELECT 1 FROM EDASYS.CELL_ARRAY_CF_MAPPING_T M WHERE  1=1 AND A.STEP_ID = 'L1110' AND A.COMPONENT_START_TIME >= TO_DATE('2018-06-03','yyyy-mm-dd')
AND A.COMPONENT_START_TIME <= TO_DATE('2018-06-27','yyyy-mm-dd')
AND A.COMPONENT_ID LIKE 'C%')

另外一个例子

更新同一张表中的两个字段

UPDATE
CELL_DEFECT_T b
SET
B.NUM_ITEM26 =- B.NUM_ITEM1,
B.NUM_ITEM27 = B.NUM_ITEM2
WHERE
b.RECORD_INDEX IN(
SELECT
B.RECORD_INDEX
FROM
cell_component_t A
LEFT JOIN CELL_DEFECT_T B ON
A.RECORD_INDEX = B.RECORD_INDEX
WHERE
A.COMPONENT_ID LIKE 'C%'
AND B.NUM_ITEM1 <> '-1'
AND B.NUM_ITEM2 <> '-1'
AND B.NUM_ITEM26 = '0'
AND A.UPDATE_TIME >= TO_DATE( '2018-05-25 10:53:24', 'YYYY-MM-DD HH24:MI:SS' )
AND A.UPDATE_TIME < TO_DATE( '2018-05-26 10:53:24', 'YYYY-MM-DD HH24:MI:SS' )
)

---------------------------------------------------------------

这里主要涉及的是 DML锁表的问题。

Oracle数据库的锁类型

在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。
当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、SX、S、X 等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁。

在数据行上只有X锁(排他锁)。在Oracle数据库中,当一个事务首次发起一个DML语句时就获得一个TX锁,该锁保持到事务被提交或回滚。当两个或多个会话在表的同一条记录上执行 DML语句时,第一个会话在该条记录上加锁,其他的会话处于等待状态。当第一个会话提交后,TX锁被释放,其他会话才可以加锁。

当Oracle数据库发生TX锁等待时,如果不及时处理常常会引起Oracle数据库挂起,或导致死锁的发生,产生ORA-60的错误。这些现象都会对实际应用产生极大的危害,如长时间未响应,大量事务失败等。

1.根据A表的某列去update B表的某列时,一定要找出A B两张表可以关联的所有字段,这样基本上不会出现"ORA-01427: 单行子查询返回多个行";
2.如果A表中真的有重复行,那就加上rownum<2条件解决。

update时 单行子查询返回多个行 SQL 错误 [1427] 处理方案相关推荐

  1. ORA-01427: 单行子查询返回多个行 出现原因及对应防止措施

    今天的一段批量更新的sql语句,稍微修改了一下就报错:ORA-01427: 单行子查询返回多个行.这个问题其实之前有遇到过几次,原因也比较简单,就是没有做好子查询的约束条件,导致该返回一条数据的地方返 ...

  2. oracle单行子查询返回多个行 order by,单行子查询返回多个行 Issue分析求助

    with order_base as --获取订单基础情况 ( select ou.order_key order_key, ou.order_quantity_i, ood.dispatch_tim ...

  3. oracle单行子查询返回多个行 order by,单行子查询返回多个行

    子查询: 用子查询能解决的问题 假想你想要写一个查询来找出挣钱比陆涛的薪水还多的人.为了解决这个问题,你需要两个查询:一 个找出陆涛的收入,第二个查询找出收入高于陆涛的人. 你可以用组合两个查询的方法 ...

  4. 单行子查询返回多个行_sql多表查询练习,习题总结

    组函数(聚合函数):组函数操作行集,给出每组的结果.组函数不象单行函数,组函数对行的集合进行操作,对每组给出一个结果.这些集合可能是整个表或者是表分成的组. 组函数和单行函数的区别: 单行函数对查询到 ...

  5. mysql子查询返回多于1行_mysql – 子查询返回超过1行

    我有以下查询 SELECT Group_concat(employeename) AS name FROM employee WHERE Find_in_set(Find_in_set(employe ...

  6. 视图单行子查询返回mysql,Oracle命令整理 - osc_sj1kgo4z的个人空间 - OSCHINA - 中文开源技术交流社区...

    常用命令 1 sqlplus  scott/tiger@192.168.47.10:1521/orcl后面不要加: sqlplus  sys/oracle  as sysdba             ...

  7. oracle输出查询返回多行,ORA-01427:单行子查询返回多行

    SQL如下: SELECT     SUM(RealNumber) AS 数量0 ,SUM(inprice) AS 单价0 ,SUM(RealNumber) * SUM(inprice) AS 金额0 ...

  8. 错误:Subquery returns more than 1 row 表示子查询返回了多行数据

    例如: select * from table1 where table1.colums=(select columns from table2) 解决方法 select * from table1 ...

  9. Oracle数据库:子查询、单行子查询,多行子查询,in,any,all语句,子查询的练习案例

    Oracle数据库:子查询.单行子查询,多行子查询,in,any,all语句,子查询的练习案例 2022找工作是学历.能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 ...

  10. 单行子查询 多行子查询 关联子查询 笔记

    1.连接基本语法 select columns_list from table_1 innner join table_2 on join_condition; eg:select e.empno,e ...

最新文章

  1. Nature子刊:Salmon不比对快速宏基因组基因定量
  2. 135.137.138.139.445端口分析
  3. android设置列表id,学习Android绑定列表的时候提示:You must supply a resource ID for a TextView,有完整示例代码...
  4. 小米0扇区完整写入_真材实料霸榜DXOMARK,小米10系列凭三个卖点“感动人心”...
  5. 06-Mapper动态代理
  6. python中continue用法案例_Python continue语句实例用法
  7. 吴军信息论40讲_吴军:有时候成功比失败更糟糕!顺势而为还是走弯路,就看一件事...
  8. Ubuntu12.04和12.10下H3C iNode客户端安装时出现找不到库的解决办法
  9. 织梦响应式酒店民宿住宿类网站织梦模板(自适应手机端)
  10. 《概率统计简明教程》
  11. 百度网盘突破下载限速
  12. 近期每日学习与工作时间安排
  13. Ubuntu 18.04 基础系统配置
  14. 程序员健身了6个月,瘦了 30 斤,怎么做到的?
  15. 迅雷下载太慢怎么办?
  16. 如何用木板做桥_木头做桥基,300年不倒(组图)
  17. Weakly Superised video anomaly detection弱监督视频异常检测
  18. python学习笔记(CSS)
  19. GitWeb服务器搭建
  20. 工地wifi覆盖解决方案怎么样

热门文章

  1. Fvuln-自动化web漏洞检测工具
  2. 国内源代码安全漏洞检测工具现状浅析
  3. Dapr专题之06Actors
  4. 从学校考的计算机是几级呀,计算机考级共分为几级
  5. delphi char数组、string和Pchar的相互转换
  6. switch语句表达式和执行流程
  7. pacman 查询_Pacman 命令记录
  8. Linux如何查看和设置DNS服务器地址
  9. python_大智慧SAR指标编写
  10. yy直播接口php,api.php · yyboss/phpcms - Gitee.com