.Net程式員學用Oracle系列(8):觸發器、任務、序列、連接

来源:http://www.cnblogs.com/hanzongze/archive/2017/01/13/Oracle-ObjectRelatedSQL2.html
-Advertisement-
Play Games

《.Net程式員學用Oracle系列:導航目錄》 本文大綱 1、 " 觸發器 " 1.1、 "創建觸發器" 1.2、 "禁用觸發器 & 啟用觸發器 & 刪除觸發器" 2、 " 任務 " 2.1、 "DBMS_JOB 包介紹" 3、 " 序列 " 3.1、 "創建序列" 3.2、 "使用序列 & 刪除 ...


《.Net程式員學用Oracle系列:導航目錄》

本文大綱

觸發器

創建觸發器

CREATE OR REPLACE TRIGGER trg_sync_staff90
-- 功能說明
AFTER INSERT OR UPDATE OR DELETE ON t_staff
FOR EACH ROW
DECLARE
  -- 定義變數
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  IF INSERTING THEN
    -- 定義DML語句
  ELSIF UPDATING THEN
    -- 定義DML語句
  ELSIF DELETING THEN
    -- 定義DML語句
  END IF;
END;

禁用觸發器 & 啟用觸發器 & 刪除觸發器

ALTER TABLE t_staff DISABLE ALL TRIGGERS; -- 禁用 t_staff 表上所有的觸發器
ALTER TABLE t_staff ENABLE ALL TRIGGERS;  -- 啟用 t_staff 表上所有的觸發器
ALTER TRIGGER trg_sync_staff90 DISABLE;   -- 禁用觸發器 trg_sync_staff90
ALTER TRIGGER trg_sync_staff90 ENABLE;    -- 啟用觸發器 trg_sync_staff90
DROP TRIGGER trg_sync_staff90;            -- 刪除觸發器 trg_sync_staff90

任務

DBMS_JOB 包介紹

創建任務的方法有很多,在實際使用過程中,我發現用 DBMS_JOB.SUBMIT 包來創建是比較方便的,語法是 DBMS_JOB.SUBMIT(jobno, what, next_date, interval),示例:

DECLARE jobno NUMBER;
BEGIN
  DBMS_JOB.SUBMIT(jobno, 'sp_sync_staff90;', SYSDATE, 'TRUNC(SYSDATE) + 1 + 2/24');
  COMMIT;
END;

估計有人會感到疑惑,為什麼創建任務的語句中 job 參數不給具體值,下麵就來簡要介紹下 DBMS_JOB.SUBMIT 各個參數及方法的用途和使用說明,如下:

  • job:任務編號,系統會自動分配。我嘗試過給一個自己喜歡的數字,但系統不認,還是自動分配了。
  • what:任務要執行的操作(如調用過程等),可通過 DBMS_JOB.WHAT(jobno,what) 修改。
  • next_date:任務的下一次執行時間,可通過 DBMS_JOB.NEXT_DATE(jobno,next_date) 修改。
  • interval:任務執行時間間隔,可通過 DBMS_JOB.INTERVAL(jobno,interval) 修改。
  • 啟動 job:DBMS_JOB.RUN(jobno)。
  • 禁用 job:DBMS_JOB.BROKEN(jobno,broken,next_date),broken 參數需要提供布爾值,next_date 參數有預設值(SYSDATE),不需要給值,broken 為 true 表示禁用任務,為 false 表示啟用任務,如 DBMS_JOB.BROKEN(135,TRUE) 表示禁用 jobno 為 135 的任務。
  • 刪除 job:DBMS_JOB.REMOVE(jobno)。

以上關於 DBMS_JOB 的這些 PLSQL 都不能像普通 SQL 語句一樣直接運行,需要寫在 BEGIN 和 END 中間,示例:

BEGIN
  DBMS_JOB.BROKEN(135,TRUE);
  COMMIT;
END;

如果想看一下整個資料庫目前的任務情況,可以通過 user_jobs 視圖來查詢,示例:

SELECT job jobno,what,to_char(next_date, 'yyyy-mm-dd hh24:mi:ss') next_date,interval FROM user_jobs;

下麵來簡要說明一下 user_jobs 視圖各主要欄位的含義,如下:

  • job:NUMBER 類型,任務的唯一編號。
  • what:VARCHAR2(4000),任務操作內容。
  • next_date:DATE 類型,下一次執行任務的時間。
  • interval:VARCHAR2(200),任務執行時間間隔。
  • log_user:提交任務的用戶。
  • priv_user:賦予任務許可權的用戶。
  • schema_user:對任務作語法分析的用戶模式。
  • last_date:最後一次成功運行任務的時間。
  • last_sec:如 hh24:mm:ss 格式的 last_date 日期的小時,分鐘和秒。
  • this_date:正在運行任務的開始時間,如果沒有運行任務則為 null。
  • this_sec:如 hh24:mm:ss 格式的 this_date 日期的小時,分鐘和秒。

interval 參數設置案例:

  • 每分鐘(的0秒)執行一次:interval => 'TRUNC(SYSDATE,''mi'') + 1/(24*60)'
  • 每小時(的0分0秒)執行一次:interval => 'TRUNC(SYSDATE,''hh24'') + 1/24'
  • 每隔 7 天執行一次:interval => 'TRUNC(SYSDATE) + 7 + 1/24'
  • 每天凌晨兩點執行一次:interval => 'TRUNC(SYSDATE) + 1 + 2/24'
  • 每周一凌晨 1 點執行一次:interval => 'TRUNC(NEXT_DAY(SYSDATE,''monday'')) + 1/24'
  • 每月 5 號凌晨 1 點執行一次:interval => 'TRUNC(LAST_DAY(SYSDATE)) + 5 + 1/24'
  • 每季度第一天凌晨 1 點執行一次:interval => 'TRUNC(ADD_MONTHS(SYSDATE,3),''Q'') + 1/24'
  • 每年 1 月 1 號凌晨 1 點執行一次:interval => 'ADD_MONTHS(TRUNC(SYSDATE,''yyyy''),12) + 1/24'

序列

我接觸的兩個基於 Oracle 開發的項目都從不用序列,以至於我都沒有使用序列的實戰經驗。寫這個章節前我特意查了下序列的定義,我覺得我們可以把序列當成是數字工廠,因為它唯一的功能就是生產等間隔的數值。

用過 Oracle 的人應該都知道,Oracle 沒有提供類似於 SQL Server 或 MySQL 中自動增長列的功能,如果我們出於對性能或空間等其它因素的考慮,需要使用自動增長列,則可以通過序列來實現類似功能。

創建序列

創建序列的標準語法如下:

CREATE SEQUENCE seq_name [INCREMENT BY n] [START WITH n] [{MAXVALUE n/NOMAXVALUE}] [{MINVALUE n/NOMINVALUE}] [{CYCLE/NOCYCLE}] [{CACHE n/NOCACHE}];

語法選項說明:

  • INCREMENT BY n:n 表示序列中連續兩個值之間的間隔,也稱作步長。如果 n 是正數則表示遞增,如果 n 是負數則表示遞減,預設是 1。
  • START WITH n:n 表示序列的起始值,即序列的第一個值,預設是 1,遞增時 n 是 minValue,遞減時 n 是 maxValue。
  • MAXVALUE n:n 表示序列的最大值,也可以選擇 NOMAXVALUE,即不設置最大值,預設是 999999999999999999999999999。
  • MINVALUE n:n表示序列的最小值,也可以選擇 NOMINVALUE,即不設置最小值,預設是 1。
  • CYCLE 和 NOCYCLE 分別表示當序列的值達到極限值後迴圈取值和不迴圈取值。
  • CACHE n:n 定義存放序列的記憶體塊的大小,預設為 20(個數字)。NOCACHE 表示不對序列進行記憶體緩衝。對序列進行記憶體緩衝,可以改善序列的性能。

使用序列 & 刪除序列

  • 使用序列
    • seq_name.CURRVAL:返回序列的當前值。
    • seq_name.NEXTVAL:返回序列的下一個值。
  • 以下情況之一不能使用序列:
    • 1、在 DELETE、SELECT、UPDATE 的子查詢中。
    • 2、在視圖或物化事物的查詢中。
    • 3、SELECT 查詢中使用了 DISTINCT 操作符。
    • 4、SELECT 查詢中有 GROUP BY 或 ORDER BY。

如果想查詢一下數據中到底有那些序列,語法如下:

SELECT * FROM USER_SEQUENCES;
SELECT * FROM ALL_SEQUENCES;
SELECT * FROM DBA_SEQUENCES;

刪除序列,示例:

DROP SEQUENCE seq_name;

連接

Oracle 中有個叫做 Database link 的東東,翻譯成中文應該是資料庫連接,為了稱呼方便,下文統一稱之為 dblink。在我跟公司一個技術專家對話時,對方提到“資料庫連接”,於是我上網查了下:dblink 是定義一個資料庫到另一個資料庫的路徑的對象,dblink 允許你查詢遠程表及執行遠程程式。

dblink 有兩種類型的,分別是公用的和私有的。一個公用資料庫鏈接對於資料庫中的所有用戶都是可用的,而一個私有鏈接僅對創建它的用戶可用。由一個用戶給另外一個用戶授權私有資料庫鏈接是不可能的,一個資料庫鏈接要麼是公用的,要麼是私有的。在任何分散式環境里,dblink 都是必要的。另外要註意的是 dblink 是單向的連接。

創建 dblink 之前先得確定三件事,第一本地資料庫和遠程資料庫之間的網路是可以正常連接的,第二創建 dblink 的賬號必須得有 CREATE DATABASE LINK 或 CREATE PUBLIC DATABASE LINK 的許可權,第三用來登錄到遠程資料庫的帳號必須得有 CREATE SESSION 許可權。

實踐告訴我,創建 dblink 的正確語法如下:

CREATE [PUBLIC] DATABASE LINK dblink_name CONNECT TO user_name IDENTIFIED BY user_pwd USING 'connect_string';

其中 connect_string 有兩種寫法,示例:

-- 第一種寫法
CREATE PUBLIC DATABASE LINK dblink168 
CONNECT TO office 
IDENTIFIED BY 123456 
USING '192.168.1.168:1521/orcl';
-- 第二種寫法
CREATE PUBLIC DATABASE LINK dblink168 
CONNECT TO office 
IDENTIFIED BY 123456 
USING '(DESCRIPTION = (
        ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.168)(PORT = 1521))
    )(
        CONNECT_DATA = (SERVICE_NAME = orcl)
    )
)';

網上很多文章中給出的創建語法里都不包含指定密碼這一項,還說如果不指定,則使用當前的用戶名和口令登錄到遠程資料庫,我反覆實驗了好多次,都是直接報語法錯誤。不過我倒是發現了一個特點,指定密碼創建成功之後,再去查看 dblink 定義的 SQL,會發現密碼指令項不見了。我猜應該是 Oracle 做了特殊的加密處理,所以如果你要創建 dblink,不必擔心顯示指定密碼後別人會看到,造成安全泄漏。

  • 使用 dblink

我覺得 dblink 真正的魅力之一便是使用方便,無論增刪改查那種語句,只需要在表名後面跟上 @dblink_name 就能操作遠程資料庫了。如要查詢 168 上用戶表中女員工的數量,示例:

SELECT COUNT(1) FROM t_staff@dblink168 t WHERE t.gender=0;

測試中我也發現一個小問題,假如我要查詢 168 上的伺服器時間,按理說寫法應該如下:

SELECT SYSDATE FROM DUAL@dblink168; -- 結果顯示出來的時間仍是本地資料庫的伺服器時間

如果為了命名更加統一,或者不想讓對方知道 dblink 的名字,也可以通過視圖或同義詞包裝一下,示例:

CREATE VIEW v_name AS SELECT * FROM table_name@dblink_name;
CREATE SYNONYM table_name FOR table_name@dblink_name;

跟 dblink 有關的幾個視圖,介紹如下:

SELECT * FROM dba_db_links; -- 查詢當前資料庫實例中所有 dblink
SELECT * FROM v$dblink;     -- 查詢當前資料庫示例中正在打開狀態的 dblink
SELECT * FROM user_sys_privs WHERE PRIVILEGE LIKE '%LINK%'; -- 查詢跟 dblink 有關的系統許可權
  • 刪除 dblink

對於非 PUBLIC 類型的 dblink,只有 owner 自己才能刪除,非 PUBLIC 類型的 dblink 沒有這個要求。刪除 dblink 的示例:

DROP [PUBLIC] DATABASE LINK dblink168;

總結

本文主要介紹了 Oracle 中相對不那麼常用的一些對象的 SQL 操作,但在實際做項目過程中,有時候它們又非常實用,所以有必要總結一下,以免用到的時候不記得語法,還得去查資料。

《.Net程式員學用Oracle系列:導航目錄》

本文聲明:如果您認為這篇文章還可以或對您有幫助,請點擊文章末尾的“推薦”按鈕。歡迎轉載、演繹或用於商業目的,但必須保留本文的署名韓宗澤,並且要在明顯位置給出原文鏈接!本人初寫博客,水平有限,若有不當之處,敬請批評指正,謝謝!



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 程式控制台出現 already exist Table "xxx",是由於項目中的Migrations(遷移文件)與連接的mysql資料庫里遷移記錄表裡的數量及名稱不一致。 ...
  • 數據持久化是還原的前提,沒有數據的持久化,就無法還原記憶體優化表的數據,SQL Server In-Memory OLTP的記憶體數據能夠持久化存儲,這意味著記憶體數據能夠在SQL Server實例重啟之後自動還原。在創建持久化的記憶體優化表時,必須設置選項:memory_optimized=on,dura ...
  • getdate():當前系統日期與時間 DATEADD(DAY,5,GETDATE()):當前日期的基礎上加上x天 DATEDIFF(DAY,'2017-01-02','2017-01-13'):返回指定的兩個日期與時間的邊界數 DATEPART(MONTH,GETDATE()):返回當前指定日期的 ...
  • 經過一段時間的學習,完成了新聞發佈的基礎功能,進行一點小總結,方便日後回顧。下麵是我的一點小總結,不足之處請勿見笑。。。 ...
  • 《.Net程式員學用Oracle系列:導航目錄》 本文大綱 1、 " 字元函數 " 1.1、 "字元函數簡介" 1.2、 "語法說明及案例" 2、 " 數字函數 " 2.1、 "數字函數簡介" 2.2、 "語法說明及案例" 3、 " 日期函數 " 3.1、 "日期函數簡介" 3.2、 "語法說明及案 ...
  • on、where、having的區別 on、where、having這三個都可以加條件的子句中,on是最先執行,where次之,having最後。有時候如果這先後順序不影響中間結果的話,那最終結果是相同的。但因為on是先把不符合條件的記錄過濾後才進行統計,它就可以減少中間運算要處理的數據,按理說應該 ...
  • ①System.Data → DataTable,DataSet,DataRow,DataColumn,DataRelation,Constraint,DataColumnMapping,DataTableMapping②System.Data.Coummon → 各種數據訪問類的基類和介面③Sys ...
  • 接觸到了一個開發需求。其中是要把NC單據表體行的欄位拼成一個字元串。例如: 出現結果字元串為:name:王一,李二,張三 語句+效果: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...