日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于SCN的查询(AS OF SCN)

發布時間:2024/8/26 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于SCN的查询(AS OF SCN) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

仍以前文中創建的表為例,既然是基于SCN的查詢,我們首先就需要得到SCN,這里我們通過DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER函數來獲取Oracle當前的SCN,之后再執行數據的修改操作

提 示

如何獲取Oracle數據庫當前的SCN?

獲取當前SCN的方式非常多,除了使用DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER函數外,也可以通過查詢V$DATABASE視圖中的CURRENT_SCN列獲取。不過,不管是通過查詢視圖,或是通過過程獲取,操作的用戶都必須擁有要操作對象的訪問權限。

例如,授予用戶使用DBMS_FLASHBACK包的權限:

  • JSSPRE>?CONN/AS?SYSDBA ?
  • Connected. ?
  • JSSPRE>?GRANT?EXECUTE?ON?DBMS_FLASHBACK?TO?SCOTT; ?
  • Grant?succeeded.?
  • 又如,授予用戶查詢V$DATABASE視圖的權限:

  • JSSPRE>?CONN/AS?SYSDBA ?
  • Connected. ?
  • JSSPRE>?GRANT?SELECT?ON?V_$DATABASE?TO?SCOTT; ?
  • Grant?succeeded.?
  • 使用DBMS_FLASHBACK包獲取當前的SCN,然后執行刪除操作并提交:

  • JSSPRE>?SELECT?DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER?FROM?DUAL; ?
  • GET_SYSTEM_CHANGE_NUMBER ?
  • ------------------------ ?
  • ?????????????????1257245 ?
  • JSSPRE>?DELETE?FLASH_TBL?WHERE?ID>10; ?
  • 10?rows?deleted. ?
  • JSSPRE>?COMMIT; ?
  • Commit?complete.?
  • 執行SELECT語句并附加AS OF SCN子句,同時指定刪除前的SCN,就可以查詢到指定SCN時對象中的記錄:

  • JSSPRE>?SELECT?*?FROM?FLASH_TBL?AS?OF?SCN?1257245; ?
  • ????ID??VL ?
  • ----------?-- ?
  • ????10??K ?
  • ????11??L ?
  • ????12??M ?
  • ????13??N ?
  • ????14??O ?
  • ????15??P ?
  • ????16??Q ?
  • ????17??R ?
  • ????18??S ?
  • ????19??T ?
  • ????20??U ?
  • ????1???A ?
  • ????2???B ?
  • ????3???C ?
  • ????4???D ?
  • ????5???E ?
  • ????6???F ?
  • ????7???G ?
  • ????8???H ?
  • ????9???I ?
  • 20?rows?selected.?
  • 執行INSERT,將刪除的數據重新恢復回表JSS_TB1:

  • JSSPRE>?INSERT?INTO?FLASH_TBL?SELECT?*?FROM?FLASH_TBL? ?
  • AS?OF?SCN?1257245?WHERE?ID>10; ?
  • 10?rows?created. ?
  • JSSPRE>?commit; ?
  • Commit?complete.?
  • 使用SCN查詢會比TIMESTAMP更加精確,事實上,即使執行Flashback Query時指定的是AS OF TIMESTAMP,Oracle也會將其轉換成SCN,這是由于Oracle內部都是通過SCN來標記操作而不是時間。

    不過在實際執行Flashback Query時,時間轉換后具體對應哪個SCN,是通過SYS用戶下的一個數據字典實現的,即SMON_SCN_TIME(時間與SCN的映射關系表):

  • JSSPRE>?DESC?SYS.SMON_SCN_TIME; ?
  • ?Name???????????????Null????????Type ?
  • ?------------------?????--------????--------------- ?
  • ?THREAD?????????????????????????NUMBER ?
  • ?TIME_MP????????????????????????NUMBER ?
  • ?TIME_DP????????????????????????DATE?
  • ?SCN_WRP????????????????????????NUMBER ?
  • ?SCN_BAS????????????????????????NUMBER ?
  • ?NUM_MAPPINGS???????????????NUMBER ?
  • ?TIM_SCN_MAP????????????????????RAW(1200) ?
  • ?SCN????????????????????????????NUMBER ?
  • ?ORIG_THREAD????????????????????NUMBER?
  • 在10g中,系統平均每3秒產生一次系統時間與SCN的匹配并存入SYS.SMON_SCN_ TIME表,因此10g版本如果使用AS OF TIMESTAMP查詢UNDO中的數據,實際獲取的數據是以指定的時間對應的SCN時的數據為基準。

    舉個例子,如SCN:339988,339989分別匹配2009-05-30 13:52:00和2009-05-30 13:57:00,則當你通過AS OF TIMESTAMP查詢2009-05-30 13:52:00或2009-05-30 13:56:59這段時間點內的任何時間,oracle都會將其匹配為SCN:339988到UNDO表空間中查找,也就說在這個時間內,不管你指定的時間點是什么,查詢返回的都將是2009-05-30 13:52:00這個時刻對應的SCN的數據。如果通過上述文字的描述仍覺得不夠形象,我想你親自執行一下SELECT SCN,TO_CHAR(TIME_DP,'YYYY-MM-DD HH24:MI:SS')FROM SYS.SMON_ SCN_TIME,會理解得更深刻一些。

    在Oracle數據庫中也可以手動進行時間和SCN的相互轉換,Oracle提供了兩個函數SCN_TO_TIMESTAMP和TIMESTAMP_TO_SCN專門干這個,例如:

  • JSSPRE>?SELECT?TIMESTAMP_TO_SCN(SYSDATE)?FROM?DUAL; ?
  • TIMESTAMP_TO_SCN(SYSDATE) ?
  • ------------------------- ?
  • ??????????????????1263291 ?
  • JSSPRE>?SELECT?TO_CHAR(SCN_TO_TIMESTAMP(1263291),? ?
  • 'YYYY-MM-DD')?FROM?DUAL; ?
  • TO_CHAR(SC ?
  • ---------- ?
  • 2009-06-02?
  • 提 示

    上面的示例中TIMESTAMP類型經過TO_CHAR格式化,只顯示了日期,千萬別以為只能精確到日期喲。Oracle中的TIMESTAMP日期類型最大能夠精確到納秒(不過一般操作系統返回的精度只到毫秒,因此即使格式化顯示出納秒的精度也沒意義,毫秒后就全是零了)。

    看起來很強大吧?其實這兩個函數的轉換依賴于SYS.SMON_SCN_TIME表,能夠轉換到的最小SCN,也正是這個表中的最小記錄,例如:

  • JSSPRE>?SELECT?SCN_WRP*4294967296+SCN_BAS?FROM?SYS.SMON_SCN_TIME ?
  • ??2??WHERE?TIME_MP=(SELECT?MIN(TIME_MP)?FROM?SYS.SMON_SCN_TIME); ?
  • SCN_WRP*4294967296+SCN_BAS ?
  • -------------------------- ?
  • ????????????????????554140?
  • 能夠轉換到的最小SCN值是554140,使用SCN_TO_TIMESTAMP查詢該SCN對應的時間:

  • JSSPRE>?SELECT?SCN_TO_TIMESTAMP(554140)?FROM?DUAL; ?
  • SCN_TO_TIMESTAMP(554140) ?
  • --------------------------------------------------------------------------- ?
  • 21-MAR-09?11.51.30.000000000?PM?
  • 比該SCN哪怕只再小1的值也無法轉換了,因為SYS.SMON_SCN_TIME表中沒有對應的映射關系:

  • JSSPRE>?SELECT?SCN_TO_TIMESTAMP(554139)?FROM?DUAL; ?
  • select?scn_to_timestamp(554139)?from?dual ?
  • ???????* ?
  • ERROR?at?line?1: ?
  • ORA-08181:?specified?number?is?not?a?valid?system?change?number ?
  • ORA-06512:?at?"SYS.SCN_TO_TIMESTAMP",?line?1?
  • 時間的轉換也是同理,所以你看,如果SYS.SMON_SCN_TIME表中不存在時間和SCN的映射關系,則執行函數轉換時就會報錯,也就是說時間和SCN之間并不存在絕對的對應關系。一切都是Oracle提供給你的,只有當它愿意讓你看,你才能夠看到。


    總結

    以上是生活随笔為你收集整理的基于SCN的查询(AS OF SCN)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。