7

私は次のようにかなり標準的な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';

このクエリをSQLDeveloperで実行すると、180万の機能が挿入された状態で正常に実行されます(select count(*) from TABLE_NAMEセッション内でこれが確認されます)。

しかし、コミットを実行すると、データが消えます!select count(*) from TABLE_NAME0の結果を返すようになりました。

何が起こっているのかを確認するために、いくつかのことを行いました。

  • の間にTruncate、テーブルスペースは解放され、挿入中に再びいっぱいになります。コミット中に変更はありません。これは、データがデータベースにあることを意味します。

  • まったく同じクエリを実行しますがand rownum < 100、最後に追加すると、コミットは機能します。と同じ1000です。

  • 私はこの質問を見つけました:oracle commitが強制終了し、DBAに「SQLトレース」を試してもらいました。これにより、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);
4

2 に答える 2

1

匿名ブロックでトランザクションをラップしてもデータは失われますか?

私の推測では、SQL Developer で 2 つの SQL ウィンドウを開いていると思います。つまり、2 つの個別のセッションを意味します。つまり、ウィンドウ 1 で SQL コードを実行し、コミットします。ウィンドウ 2 では、ウィンドウ 1 で行われた変更はコミットされません。

Truncate table は暗黙的なコミットを行います。したがって、挿入+コミットが完了するまで、テーブルは空になります。

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;

挿入で同じ数のブロックを取得するためだけにデータベースがすべてのブロックを解放しないように、再利用ストレージで切り捨てを使用する必要があります。

常にデータを利用できるようにしたい/必要がある場合は、より良い(しかしより長い)方法があります

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;
于 2014-11-10T13:08:25.850 に答える
-2

おそらく、あなたは気づいていないトリガーを持っていたのでしょう。削除されたテーブルとトリガーの履歴を保存している可能性があるオラクルの recyclebin テーブルを確認できますか?

Select * from recyclebin;

参照: http://www.oraclebin.com/2012/12/recyclebinflashback.html

于 2013-01-05T15:43:32.817 に答える