我有一个相当标准的SQL查询,如下所示:
TRUNCATE TABLE TABLE_NAME;
INSERT INTO TABLE_NAME
(
UPRN,
SAO_START_NUMBER,
SAO_START_SUFFIX,
SAO_END_NUMBER,
SAO_END_SUFFIX,
SAO_TEXT,
PAO_START_NUMBER,
PAO_START_SUFFIX,
PAO_END_NUMBER,
PAO_END_SUFFIX,
PAO_TEXT,
STREET_DESCRIPTOR,
TOWN_NAME,
POSTCODE,
XY_COORD,
EASTING,
NORTHING,
ADDRESS
)
SELECT
BASIC_LAND_AND_PROPERTY_UNIT.UPRN,
LAND_AND_PROPERTY_IDENTIFIER.SAO_START_NUMBER AS SAO_START_NUMBER,
LAND_AND_PROPERTY_IDENTIFIER.SAO_START_SUFFIX AS SAO_START_SUFFIX,
LAND_AND_PROPERTY_IDENTIFIER.SAO_END_NUMBER AS SAO_END_NUMBER,
LAND_AND_PROPERTY_IDENTIFIER.SAO_END_SUFFIX AS SAO_END_SUFFIX,
LAND_AND_PROPERTY_IDENTIFIER.SAO_TEXT AS SAO_TEXT,
LAND_AND_PROPERTY_IDENTIFIER.PAO_START_NUMBER AS PAO_START_NUMBER,
LAND_AND_PROPERTY_IDENTIFIER.PAO_START_SUFFIX AS PAO_START_SUFFIX,
LAND_AND_PROPERTY_IDENTIFIER.PAO_END_NUMBER AS PAO_END_NUMBER,
LAND_AND_PROPERTY_IDENTIFIER.PAO_END_SUFFIX AS PAO_END_SUFFIX,
LAND_AND_PROPERTY_IDENTIFIER.PAO_TEXT AS PAO_TEXT,
STREET_DESCRIPTOR.STREET_DESCRIPTOR AS STREET_DESCRIPTOR,
STREET_DESCRIPTOR.TOWN_NAME AS TOWN_NAME,
LAND_AND_PROPERTY_IDENTIFIER.POSTCODE AS POSTCODE,
BASIC_LAND_AND_PROPERTY_UNIT.GEOMETRY AS XY_COORD,
BASIC_LAND_AND_PROPERTY_UNIT.X_COORDINATE AS EASTING,
BASIC_LAND_AND_PROPERTY_UNIT.Y_COORDINATE AS NORTHING,
decode(SAO_START_NUMBER,null,null,SAO_START_NUMBER||SAO_START_SUFFIX||' ')
||decode(SAO_END_NUMBER,null,null,SAO_END_NUMBER||SAO_END_SUFFIX||' ')
||decode(SAO_TEXT,null,null,SAO_TEXT||' ')
||decode(PAO_START_NUMBER,null,null,PAO_START_NUMBER||PAO_START_SUFFIX||' ')
||decode(PAO_END_NUMBER,null,null,PAO_END_NUMBER||PAO_END_SUFFIX||' ')
||decode(PAO_TEXT,null,null,'STREET RECORD',null,PAO_TEXT||' ')
||decode(STREET_DESCRIPTOR,null,null,STREET_DESCRIPTOR||' ')
||decode(POST_TOWN,null,null,POST_TOWN||' ')
||Decode(Postcode,Null,Null,Postcode) As Address
From (Land_And_Property_Identifier
Inner Join Basic_Land_And_Property_Unit
On Land_And_Property_Identifier.Uprn = Basic_Land_And_Property_Unit.Uprn)
Inner Join Street_Descriptor
On Land_And_Property_Identifier.Usrn = Street_Descriptor.Usrn
Where Land_And_Property_Identifier.Postally_Addressable='Y';
如果我在SQL Developer中运行此查询,它运行正常,插入了180万个功能(会话中的select count(*) from TABLE_NAME
确认了这一点。)
但是当我运行提交时,数据就会消失! select count(*) from TABLE_NAME
现在返回0结果。
我们已经做了很多尝试,看看发生了什么:
在Truncate
期间,表空间被释放,并且在插入期间它再次被填充。提交期间没有变化。这意味着数据存在于数据库中。
如果我执行完全相同的查询但附加了and rownum < 100
,则提交有效。与1000
相同。
我发现了这个问题:oracle commit kills并让我们的DBA尝试“SQL Trace”。这产生了一个> 4GB的文件,当用TKPROF解析时产生了120页的报告,但是我们不知道如何阅读它并且那里没有明显的错误。
我们的错误日志中没有任何内容。并且在提交过程中显然没有错误。
在此过程中会有一个触发器/序列增加180万。
我现在已经重复了4次,但结果总是一样。
所以我的问题很简单 - 提交期间数据发生了什么?我们怎么知道?感谢。
注意:这在过去运行良好,所以我不相信SQL本身有任何问题。
编辑:解决问题,方法是从头开始重新创建表格。现在,当我插入它时,与之前的2000相比只需要500秒。并且提交是即时的;当它被打破时,提交需要4000秒! 我仍然不知道它为什么会发生。
对于那些询问,创建表语法:
CREATE TABLE TABLE_NAME
(
ADDRESS VARCHAR2(4000),
UPRN NUMBER(12),
SAO_START_NUMBER NUMBER(4),
SAO_START_SUFFIX VARCHAR2(1),
SAO_END_NUMBER NUMBER(4),
SAO_END_SUFFIX VARCHAR2(1),
SAO_TEXT VARCHAR2(90),
PAO_START_NUMBER NUMBER(4),
PAO_START_SUFFIX VARCHAR2(1),
PAO_END_NUMBER NUMBER(4),
PAO_END_SUFFIX VARCHAR2(1),
PAO_TEXT VARCHAR2(90),
STREET_DESCRIPTOR VARCHAR2(100),
TOWN_NAME VARCHAR2(30),
POSTCODE VARCHAR2(8),
XY_COORD MDSYS.SDO_GEOMETRY,
EASTING NUMBER(7),
NORTHING NUMBER(7)
)
CREATE INDEX TABLE_NAME_ADD_IDX ON TABLE_NAME (ADDRESS);
答案 0 :(得分:0)
如果将事务封装在匿名块中,您是否仍会丢失数据?
我的猜测是你在SQL Developer中打开两个SQL窗口,这意味着两个单独的会话。即在窗口1中运行SQL代码并执行提交;在窗口2中,不会提交在窗口1中完成的更改。
Truncate表执行隐式提交。因此,在insert + commit完成之前,表将为空。
begin
execute immediate 'truncate table table_name reuse storage'; --use "reuse" if you know the data will be of similar size
-- implicit commit has occured and the table is empty for all sessions
insert into table_name (lots)
select lots from table2;
commit;
end;
您应该将truncate与重用存储一起使用,这样数据库就不会释放所有块,只是为了获取插入中相同数量的块。
如果您希望/需要始终提供数据,则可以使用更好(但更长)的方法
begin
savepoint letsgo;
delete from table_name;
insert into table_name (lots)
select lots from table2;
commit;
exception
when others then
rollback to letsgo;
end;
答案 1 :(得分:-1)
可能你有一个你没注意到的触发器。你能检查oracle的recyclebin表,它可能存储你删除的表的历史并触发吗?
Select * from recyclebin;
参考文献:http://www.oraclebin.com/2012/12/recyclebinflashback.html