Oracle insert数据的新方法 及死锁解决办法

在开发过程中,发现了一串代码,如下:


		INSERT INTO acc_invoice_print_list (instance_id, invoice_id, charge_name,currency,unit_price,unit_num,amount,invoice_amount,unit_name,specifications)
		SELECT TO_CHAR(SYSDATE,'YYYYMMDD') || seq_charge_id.nextval instance_id, invoice_id, charge_name,currency,unit_price,unit_num,amount,invoice_amount,unit_name,specifications
        FROM (
		
			SELECT #insertList[].invoice_id# invoice_id,
					#insertList[].charge_name# charge_name,
					#insertList[].currency# currency,
					#insertList[].unit_price# unit_price,
					#insertList[].unit_num# unit_num,
					#insertList[].amount# amount,
					#insertList[].invoice_amount# invoice_amount,
					#insertList[].unit_name# unit_name,
					#insertList[].specifications# specifications
			FROM dual
		)

在研究之后发现,这串代码中的insert语句后面没有values,而是在写好相应的字段名之后,在后面加了一个select语句,而此条select语句返回的是一个结果集,如果代码可以执行成功,也就意味着通过 insert into table_name1(column1, column2, column3) select column1, column2, column3 from table_name2;这种形式可以插入多条数据,遂自己验证了一下。

首先创建一个表;

create table test111(
       job_id number(15) not null primary key,
       job_no varchar2(15),
       sale_corp_id number(10)
)

然后利用上面的格式写入insert语句;

insert into test111
  (job_id, job_no, sale_corp_id)
  select h.job_id, h.job_no, h.sale_corp_id
    from job_head h
   where h.create_date > to_date('2019/09/21', 'yyyy/MM/dd')

最后成功插入。

这种操作在复制表数据的时候可能会有一定的便捷性,不需使用循环等操作。

补充:

在插入数据之后,没有及时提交导致了进程死锁,下面附带解决死锁的方法。

1. 查找是否存在进程死锁;

select username, lockwait, status, machine, program
  from v$session
 where sid in (select session_id from v$locked_object)

其中status可能有两个值,active,inactive。其中active指的是正在执行(一直处于执行状态),inactive指的是等待执行。

例如:

--SQL1
delete from test111;
--SQL2
delete from test111;

先执行SQL1,不提交,再执行SQL2,执行查询死锁的SQL,就会发现有两条记录,一个active,一个inactive。不论是active还是inactive都是不正常的进程,应该手动清除。

2. 通过以下语句可查询到具体是那个语句造成了死锁情况。

select sql_text
  from v$sql
 where hash_value in
       (select sql_hash_value
          from v$session
         where sid in (select session_id from v$locked_object))

3. 然后通过以下SQL查询到死锁进程的相关信息

select s.username,
       l.object_id,
       l.session_id,
       s.serial#,
       l.oracle_username,
       l.os_user_name,
       l.process
  from v$locked_object l, v$session s
 where l.session_id = s.sid;

4. 最后杀死进程

  --session_id, serial#是上面查询到的结果中的值
 alter system kill session ‘session_id,serial#’; 

进程死锁参考了原文

你可能感兴趣的:(工作总结)