.Net程式員學用Oracle系列(27):PLSQL 之游標、異常和事務

来源:http://www.cnblogs.com/hanzongze/archive/2017/05/17/Oracle-plsql-2.html
-Advertisement-
Play Games

" 1、游標 " "1.1、游標屬性" "1.2、隱式游標" "1.3、游標處理及案例" " 2、異常 " "2.1、異常類別" "2.2、異常函數" "2.3、異常處理及案例" " 3、事務 " "3.1、開始事務、結束事務" "3.2、自治事務" "3.3、事務處理及案例" " 4、總結 " 1 ...


1、游標

游標是一種數據處理機制,它提供了在結果集中依次瀏覽一行或多行數據的能力。游標就相當於是一個指針,它可以指定結果中的任何位置,然後允許用戶對指定位置的數據進行處理。Oracle 中的游標分為顯示游標和隱式游標兩種。

1.1、游標屬性

每個游標和游標變數都有四個屬性:%FOUND、%ISOPEN、%NOTFOUND 和 %ROWCOUNT。當附加到游標或游標變數時,這些屬性返回有關執行數據操作語句的狀態信息。

1、%ISOPEN:如果游標處於打開狀態,則 cursor_name%ISOPEN 返回 TRUE;否則返回FALSE。

2、%FOUND:在游標被打開之後,第一次提取數據行之前,cursor_name%FOUND 會返回 NULL。此後,如果最近一次提取返回了一行數據,則返回 TRUE,如果最近一次提取未能返回一行數據,則返回 FALSE。

3、%NOTFOUND:在游標被打開之後,第一次提取數據行之前,cursor_name%NOTFOUND 返回NULL。此後,如果最近一次提取返回了一行數據,則返回 FALSE,如果最近一次提取未能返回一行數據,則返回 TRUE。

4、%ROWCOUNT:在游標被打開之後,第一次提取數據行之前,cursor_name%ROWCOUNT 返回 0。此後,它返回到目前為止已提取的行數。如果最近一次提取返回了一行,則該數字會遞增。

1.2、隱式游標

顯示游標主要用於處理查詢語句,尤其是查詢結果為多條記錄的情況,需要由程式員顯式地聲明一個游標來單獨處理這些行。而對於 SELECT ... INTO ...、INSERT、DELETE、UPDATE 等語句,Oracle 系統會自動地為這些操作設置隱式游標,併為該游標的取名為 SQL。隱式游標的相關操作均由 Oracle 系統自動完成,無需用戶進行任何諸如打開或關閉之類的處理。

用戶可以通過隱式游標的名稱和屬性來瞭解操作的狀態和結果,進而控製程序的流程。但需要註意的是,通過 SQL 游標名只能訪問前一個 DML 操作或單行 SELECT 操作的游標屬性(所以通常得在執行完操作之後,立馬使用 SQL 游標名來訪問屬性)。因為在隱式游標的工作區中,所存放的數據是與用戶自定義的顯示游標無關的、最新處理的一條 SQL 語句所包含的數據。

關於單行 SELECT 操作的隱式游標,還 3 點需要註意:

  • 1、每一個 單行 SELECT 隱式游標必須得有一個 INTO 子句。
  • 2、INTO 子句後接收數據的變數的數據類型要與對應列的數據類型一致。
  • 3、隱式游標一次只能返回一條數據。

示例:

DECLARE
  v_course_id demo.t_course.course_id%TYPE := 7;
BEGIN
  DBMS_OUTPUT.PUT_LINE('SQL%ROWCOUNT: '||SQL%ROWCOUNT); -- NULL
  UPDATE demo.t_course t SET t.course_desc='7' WHERE t.course_id=v_course_id;
  DBMS_OUTPUT.PUT_LINE('SQL%ROWCOUNT: '||SQL%ROWCOUNT); -- 1
  
  IF SQL%ISOPEN THEN  -- false
    DBMS_OUTPUT.PUT_LINE('SQL%ISOPEN is true.');
  END IF;
  
  IF SQL%FOUND THEN -- true
    DBMS_OUTPUT.PUT_LINE('SQL%FOUND is true.');
  END IF;
  
  IF SQL%NOTFOUND THEN -- false
    DBMS_OUTPUT.PUT_LINE('SQL%NOTFOUND is true.');
  END IF;
END;

1.3、游標處理及案例

在使用游標之前,必須先聲明游標。可以在聲明的時候給游標取一個名字,並將其與特定的查詢想關聯,還可以同時為游標指定一個返回類型。在通過游標提取數據之前,還得先打開游標,然後通過游標提取行。當處理完所有行之後,應立即關閉游標變數,以免造成資源浪費。

示例 1(遍歷輸出所有課程名稱):

DECLARE
  TYPE course_type IS REF CURSOR RETURN demo.t_course%ROWTYPE; -- 定義游標類型
  cursor1 course_type; -- 定義一個游標 cursor1
  v_course demo.t_course%ROWTYPE; -- 定義一個表示 t_course 表中行的變數
BEGIN
  IF NOT cursor1%ISOPEN THEN -- 如果游標不是打開狀態,如果試圖打開一個已打開的游標時將會出現錯誤,所以應該要判斷一下
    OPEN cursor1 FOR SELECT t.* FROM demo.t_course t; -- 打開游標,這裡得確保 SELECT 列表和游標變數的數據類型一致
    LOOP
      FETCH cursor1 INTO v_course; -- 從游標中提取行
      EXIT WHEN cursor1%NOTFOUND; -- 如果找不到數據行了就退出迴圈
      DBMS_OUTPUT.PUT_LINE('課程名稱:'||v_course.course_name); -- 列印被提取的數據
    END LOOP;
  END IF;
  CLOSE cursor1; -- 關閉游標,如果試圖關閉一個已關閉的游標時也會出現錯誤
END;

示例 2(遍歷輸出所有課程名稱,並分段顯示):

DECLARE
  cursor1 SYS_REFCURSOR;
  v_course_name demo.t_course.course_name%TYPE;
BEGIN
  OPEN cursor1 FOR SELECT t.course_name FROM demo.t_course t;
  LOOP
    FETCH cursor1 INTO v_course_name;
    EXIT WHEN cursor1%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(cursor1%ROWCOUNT||':'||v_course_name);
    IF cursor1%ROWCOUNT=2 THEN
      DBMS_OUTPUT.PUT_LINE('--- 已輸出兩行記錄 ---');
    END IF;
  END LOOP;
  CLOSE cursor1;
END;

上例中的 SYS_REFCURSOR 是 Oracle 系統提供的,用於傳遞游標變數,與使用自定義的“REF CURSOR”並無本質區別

示例 3(輸出指定課程的名稱和描述):

DECLARE
  v_course_id demo.t_course.course_id%TYPE := 1;
  v_course_name demo.t_course.course_name%TYPE;
  v_course_desc demo.t_course.course_desc%TYPE;
  CURSOR cursor1 IS 
    SELECT t.course_name,t.course_desc FROM demo.t_course t WHERE t.course_id=v_course_id;
BEGIN
  OPEN cursor1;
  FETCH cursor1 INTO v_course_name,v_course_desc;
  IF cursor1%FOUND THEN
    DBMS_OUTPUT.PUT_LINE('名稱:'||v_course_name||CHR(10)||'描述:'||v_course_desc);
  END IF;
  CLOSE cursor1;
END;

示例 4(輸出指定課程的相關信息):

DECLARE
  CURSOR cursor1 RETURN demo.t_course%ROWTYPE IS 
    SELECT t.* FROM demo.t_course t WHERE t.course_id=2;
  v_course t_course%ROWTYPE;
BEGIN
  OPEN cursor1;
  FETCH cursor1 INTO v_course;
  IF cursor1%FOUND THEN
    DBMS_OUTPUT.PUT_LINE(v_course.course_id||CHR(10)||v_course.course_name||CHR(10)||v_course.course_desc);
  END IF;
  CLOSE cursor1;
END;

示例 5(創建一個提取信息的程式包,用於根據條件提取不同表中的信息):

CREATE PACKAGE pkg_take_info AS
  TYPE cursor_type IS REF CURSOR;
  PROCEDURE sp_take_info(cursor1 IN OUT cursor_type,choice INT);
END pkg_take_info;

CREATE PACKAGE BODY pkg_take_info AS
  PROCEDURE sp_take_info(cursor1 IN OUT cursor_type,choice INT) IS
  BEGIN
    IF choice=1 THEN
      OPEN cursor1 FOR SELECT t.* FROM demo.t_course t;
    ELSIF choice=2 THEN
      OPEN cursor1 FOR SELECT t.* FROM demo.t_staff t;
    ELSIF choice=3 THEN
      OPEN cursor1 FOR SELECT t.* FROM demo.t_field_enum t;
    END IF;
    CLOSE cursor1;
  END;
END pkg_take_info;

2、異常

異常(PL/SQL 運行時錯誤)可能源自設計錯誤、編碼錯誤、硬體故障以及許多其它來源。我們往往無法預期所有可能的異常,但可以編寫異常處理模塊,讓程式繼續有效運行。

2.1、異常類別

  • 內部定義異常:運行時系統會自動引發內部定義的異常。典型的內部定義異常如 ORA-00060(在等待資源時檢測到死鎖)和 ORA-27102(記憶體不足)。內部定義的異常總是有一個錯誤代碼,但沒有名稱。
  • 預定義異常:預定義的異常也是內部定義的異常,但 PL/SQL 給它取了名字。例如,ORA-06500(PL/SQL:存儲錯誤)就有預定義名稱 STORAGE_ERROR。
  • 用戶自定義異常:可以在任何 PL/SQL 匿名塊、子程式或程式包的聲明部分聲明自己的異常。例如,可以聲明一個名為餘額不足的異常來標記已透支的銀行帳戶,併在異常處理模塊中拋出該異常。

2.2、異常函數

1、錯誤代碼 SQLCODE 函數

在異常處理程式中,SQLCODE 函數返回正在處理的異常的數字代碼。在異常處理程式之外,SQLCODE 返回 0。對於內部定義的異常,數字代碼是有關 Oracle 資料庫錯誤的編號。除“no data found”數字代碼為 +100 之外,該數字一般是負數。對於用戶自定義的異常,數字代碼預設為 +1 或與EXCEPTION_INIT編譯指示異常相關聯的錯誤代碼。在 SQL 語句無法調用 SQLCODE。

2、錯誤消息 SQLERRM 函數

SQLERRM 函數返回與錯誤代碼相關聯的錯誤消息。

語法:

SQLERRM [(error_code)]

示例:

BEGIN
  DBMS_OUTPUT.PUT_LINE(SQLERRM);         -- ORA-0000: normal, successful completion
  DBMS_OUTPUT.PUT_LINE(SQLERRM(100));    -- ORA-01403: 未找到任何數據
  DBMS_OUTPUT.PUT_LINE(SQLERRM(-60));    -- ORA-00060: 等待資源時檢測到死鎖
  DBMS_OUTPUT.PUT_LINE(SQLERRM(-27102)); -- ORA-27102: 記憶體不足
  DBMS_OUTPUT.PUT_LINE(SQLERRM(-6500));  -- ORA-06500: PL/SQL: 存儲錯誤
END;

2.3、異常處理及案例

定義異常

語法:

exception_name EXCEPTION;

如上所述,定義用戶自定義異常的方法非常簡單,只需給出異常名稱即可。另外,還可以通過EXCEPTION_INIT將該名稱分配給內部定義的異常,具體用法可參考:《Oracle Database PL/SQL Language Reference: EXCEPTION_INIT Pragma》

拋出異常

PL/SQL 中的 RAISE 與 C# 中的 throw 相似,RAISE 語句的作用是在 Oracle 中拋出異常。只要在異常處理模塊之外,定義好用戶自定義異常並指定異常名稱,就可以通過 RAISE 語句明確引發該異常。如果省略異常名稱,則 RAISE 語句將會重新檢查當前異常。

語法:

RAISE [ exception_name ];

任何 PL/SQL 塊(包括匿名塊、子程式和程式包)都可以有一個異常處理模塊,用來處理一或多個異常。對於命名異常,可以編寫一個特定的異常處理程式,而不是使用 OTHERS 異常來處理它。特定的異常處理程式比 OTHERS 異常處理程式更有效,因為後者還必須調用一個函數來確定它正在處理哪個異常。

如果沒有異常處理程式,您必須檢查可能發生的每一個可能的錯誤,然後處理它。很容易忽略可能的錯誤或可能發生的地方,特別是如果錯誤不能立即被檢測到(例如,壞數據可能無法檢測,直到在計算中使用它)。這會導致大量錯誤處理代碼散佈在整個程式中。

使用異常處理程式,您不需要知道每一個可能的錯誤或其可能發生的任何地方。您只需在每個可能發生錯誤的程式段中包含一個異常處理部分。在異常處理部分,您可以包括特定和未知錯誤的異常處理程式。如果塊中的任何位置(包括子塊內)發生錯誤,則異常處理程式處理它。錯誤處理代碼在塊的異常處理部分中被隔離。

異常模塊語法:

EXCEPTION
  WHEN ex_name_1 THEN statements_1;
  WHEN ex_name_2 OR ex_name_3 THEN statements_2;
  WHEN OTHERS THEN statements_3;

當塊中可執行部分出現異常時,可執行部分停止執行,異常處理部分開始執行。例如,出現異常ex_name_1,則statements_1會被運行;如果出現異常ex_name_2ex_name_3,則statements_2會被運行。如果在沒有異常處理程式的塊中引發異常,則異常傳播。也就是說,異常在連續的封閉塊中重現本身,直到被處理,如果沒有被處理,則 PL/SQL 會向調用者或主機環境返回未處理的異常錯誤。

示例(ZERO_DIVIDE):

DECLARE
  stock_price NUMBER(18,6) := 8; -- 股票市場價格
  net_earnings NUMBER(18,6) := 0; -- 凈收益
  pe_ratio NUMBER(18,6); -- 市盈率
BEGIN
  pe_ratio := stock_price/net_earnings; -- 除數為零
  DBMS_OUTPUT.PUT_LINE('Price/earnings ratio: '||pe_ratio);
EXCEPTION
  WHEN ZERO_DIVIDE THEN
    DBMS_OUTPUT.PUT_LINE('Zero earnings!');
    pe_ratio := NULL;
END;

示例(NO_DATA_FOUND):

DECLARE
  v_course_id demo.t_course.course_id%TYPE := 8;
  v_course_name demo.t_course.course_name%TYPE;
  v_course_desc demo.t_course.course_desc%TYPE;
BEGIN
  SELECT t.course_name,t.course_desc INTO v_course_name,v_course_desc 
  FROM demo.t_course t 
  WHERE t.course_id=v_course_id;
  
  DBMS_OUTPUT.PUT_LINE('課程名稱:'||v_course_name);
  DBMS_OUTPUT.PUT_LINE('課程說明:'||v_course_desc);
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE('No such course!');
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('未知錯誤!');
END;

示例(VALUE_ERROR):

BEGIN
  DECLARE
    credit_limit NUMBER(5) := 200000;
  BEGIN
    NULL;
  END;
EXCEPTION
  WHEN VALUE_ERROR THEN
    DBMS_OUTPUT.PUT_LINE('賦值時出錯!');
END;

示例(用戶自定義異常):

DECLARE
  v_amount NUMBER(18,6) := 1.00;
  v_due_date DATE := TO_DATE('2017-01-07','yyyy-mm-dd');
  no_money EXCEPTION;
  past_due EXCEPTION;
BEGIN
  IF v_amount<=0 THEN
    RAISE no_money;
  END IF;
  
  IF v_due_date<demo.fn_today THEN
    RAISE past_due;
  END IF;
  
EXCEPTION
  WHEN no_money THEN
    DBMS_OUTPUT.PUT_LINE('沒錢了!');
  WHEN past_due THEN
    DBMS_OUTPUT.PUT_LINE('逾期了!');
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('出現未知異常!');
    RAISE;
END;

更多 Oracle 異常處理細節及案例,請參考:《Oracle Database PL/SQL Language Reference: PL/SQL Error Handling》

3、事務

事務是資料庫區別於文件系統的特性之一。事務會把資料庫從一種一致狀態轉變為另一種一致狀態。Oracle 中的事務體現了所有必要的 ACID 特性。ACID 是以下 4 個詞的縮寫。

  • 原子性(Atomicity):事務中的所有動作要麼都發生,要麼都不發生。
  • 一致性(Consistency):事務將資料庫從一種一致狀態轉變為下一種一致狀態。
  • 隔離性(Isolation):一個事務的影響在該事務提交前對其它事務都不可見。
  • 持久性(Durability):事務一旦提交,其結果就是永久性的。

事務是包含一個或多個 SQL 語句的邏輯單元。事務中所有 SQL 語句的效果可以是全部提交(應用於資料庫)或全部回滾(從資料庫撤消)。

3.1、開始事務、結束事務

在 Oracle 中不需要用專門的語句來“開始事務”。事務會在遇到第一個可執行的 SQL 語句時處隱式開始。也可以使用 SET TRANSACTION 或 DBMS_TRANSACTION 包來顯式地開始一個事務,但這一步並非是必須的。

當執行了不帶 SAVEPOINT 子句的 COMMIT(提交)或 ROLLBACK(回滾)時,事務就會被顯式地結束。當執行了 DDL 或 DCL 語句時,事務就會被自動提交,也就是隱式地結束。如果用戶斷開與 Oracle 的連接,當前事務自動提交。如果用戶進程異常終止,當前事務自動回滾。如用戶退出 SQLPlus 會話時,若沒有提交或回滾事務,SQLPlus 會自動為用戶提交。當系統崩潰時事務也會被隱式提交。我們不能過度依賴這些隱式行為,因為將來這些行為可能會改變。

提交意味著用戶明確或暗示地要求將事務中的更改設置為永久性。當用戶發出 COMMIT 語句時,會發出顯式請求。在應用程式正常終止或 DDL 操作完成後,會發生隱式請求。只有事務提交之後,事務的 SQL 語句所做的更改才會變得永久可見。在事務提交後發出的查詢將看到已提交的更改。

Oracle 中的 DDL 語句具有原子性,不過只是在語句級保證原子性,如果操作成功則提交,否則回滾 DDL 操作。提交所有未完成的工作,結束當前的所有事務。只要執行了 DDL 語句,就可以將現有的事務立即提交,並完成後面的 DDL 命令,這些 DDL 命令可能提交從而得到持久的結果,也可能因為出現錯誤而回滾。儘管 DDL 並不違反 ACID 概念,但 DDL 語句會提交的這一點確實需要註意。

ORACLE 伺服器會執行隱式的存儲點。如果在執行過程中的任何時候,一旦 SQL 語句運行出錯,就會回滾該語句的所有效果。回滾的效果就好像是該語句從未被運行過。回滾意味著撤消對未提交事務中的SQL語句執行的數據的任何更改。Oracle 使用 undo 表空間(或回滾段)來存儲舊值。重做日誌包含更改記錄。Oracle 允許您回滾整個未提交的事務。還可以將未提交事務的尾部部分回滾到稱為保存點的標記。

3.2、自治事務

自治事務(autonomous transaction)允許你創建一個“事務中的事務”,它能獨立於其父事務提交或回滾。利用自治事務,可以掛起當前執行的事務,開始一個新事務,完成一些工作,然後提交或回滾,所有這些都不影響當前所執行事務的狀態。換句話說,自治事務允許從某個事務中調用另一個獨立的事務。一旦被調用,自治事務就完全獨立於調用它的主事務。在自治事務中,看不到主事務中發生的任何未提交的更改,並且不與主事務共用任何鎖或資源。

在自治事務中還可以調用另一個自治事務,除了資源限制外,對於可以調用多少層級的自治事務沒有限制。自治事務與其調用的事務之間可能會出現死鎖,當 Oracle 檢測到這種死鎖時會返回錯誤,應用程式開發人員應極力避免這種死鎖的發生。當一個自治塊調用另一個自治塊或其自身時,被調用的塊不會與調用塊共用任何事務上下文。然而,當自主塊調用非自主塊(即,未聲明為自主事務的塊)時,被調用塊繼承了調用自主塊的事務上下文。

自動事務對於實現需要獨立執行的操作非常有用,無論調用事務是否提交或回滾,例如記錄錯誤日誌或信息型消息,從而可以獨立於父事務完成提交。

語法(聲明為自治事務):

PRAGMA AUTONOMOUS_TRANSACTION;

3.3、事務處理及案例

COMMIT:結束當前會話事務,並使得已做的所有修改成為永久性的。

語法:

COMMIT [WORK] [COMMENT clause] [WRITE clause] [FORCE clause];

預設是 COMMIT WORK WRITE WAIT IMMEDIATE,表示同步提交,如果明確寫出 COMMIT NOWAIT 則表示非同步提交。PL/SQL 一直都透明的使用非同步提交,而流行的 API(ODBC 和 JDBC) 預設會自動提交事務。如果應用需要與人交互,就應當使用同步提交。對於面向客戶的線上應用,不能把非同步提交做為改善性能的手段。非同步應用只適用於面向批處理的應用,也就是那些出現故障時能自動重啟的應用。互動式應用在出現故障時無法自動重啟,必須由人來重新執行事務。

ROLLBACK:回滾當前會話事務,並撤銷所有未提交的修改。

語法:

ROLLBACK [WORK] [TO [SAVEPOINT] savepoint_name | FORCE 'string'];

SAVEPOINT:允許你在事務上下文中創建保存點,一個事務可以有多個保存點,將一個事務分為多個較小的部分。保存點只在事務執行過程中有效,事務結束即被釋放。保存點在應用程式中同樣有用。如果一個過程包含幾個函數,那麼可以在每個函數開始之前創建一個保存點。然後,如果函數失敗,則在函數開始之前很容易將數據返回到其狀態,並使用修改後的參數重新運行該函數或執行恢復操作。

ROLLBACK TO :這個語句與 SAVEPOINT 一起使用,可以把事務回滾到保存點,而不回滾該保存點之前的任何工作。

SET TRANSACTION:允許你設置不同的事務屬性,如事務的名稱、隔離級別以及事務是只讀的還是可讀寫的。SET TRANSACTION 語句執行的操作僅影響當前事務,而不影響其它用戶或其它事務。

語法:

SET TRANSACTION [READ ONLY | READ WRITE]
                [ISOLATION LEVEL [SERIALIZE | READ COMMITED]
                [USE ROLLBACK SEGMENT 'segment_name']
                [NAME 'transaction_name'];

示例 1:

BEGIN
  INSERT INTO t3(f1) VALUES(1); -- 第一條修改數據的語句即事務的開始
  SAVEPOINT p1; -- 創建一個標記點
  INSERT INTO t3(f1) VALUES(2);
  ROLLBACK TO p1; -- 回滾到 p1,這樣 p1 之後數據 2 就丟失了,只剩下 1
  INSERT INTO t3(f1) VALUES(3);
  COMMIT; -- 提交事務,所有保存點均失效,表中數據 1 和 3
END;

示例 2:

BEGIN
  SET TRANSACTION READ WRITE NAME 'tran1';
  SAVEPOINT p1; -- 創建一個標記點
  INSERT INTO t3(f1) VALUES(4);
  COMMIT; -- 提交事務
  INSERT INTO t3(f1) VALUES(5);
  ROLLBACK; -- 回滾事務,表中數據 1、3、4
END;

想要瞭解更多 Oracle 中的事務處理知識可參考:

4、總結

本文主要講述了 PL/SQL 中的游標、異常和事務的基本概念和基本用法,且特別地講述了 Oracle 中的兩個非常特殊的事物——隱式游標和自治事務。

本文鏈接http://www.cnblogs.com/hanzongze/p/Oracle-plsql-2.html
版權聲明:本文為博客園博主 韓宗澤 原創,作者保留署名權!歡迎通過轉載、演繹或其它傳播方式來使用本文,但必須在明顯位置給出作者署名和本文鏈接!本人初寫博客,水平有限,若有不當之處,敬請批評指正,謝謝!


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

-Advertisement-
Play Games
更多相關文章
  • ShareSDK第三方登錄 ...
  • activity_login.xml 快速登錄(獲得驗證碼和登錄) 賬號登錄(登錄和切換密碼明文) ...
  • fragment_me.xml MeFragment.java ...
  • 今天想要與大家一起分享的是近一個星期內開發的一個新app——乾貨集中營客戶端,其實網上已經有許多類似的項目,代碼家也在他的乾貨集中營中推薦了幾款優秀的作品,我也借鑒了其中的一些,自己開發出一款乾貨集中營客戶端,目前項目已經發佈到github,如果你想瞭解整個工程的具體內容,那麼你可以fork或者cl... ...
  • 遇到 vendor tools 無法 work 時, 最好的方法直接請 vendor 來, 為什麼呢? 因為 tool 可能 有版本的問題, 譬如: vendor tool A tool 在 build B 版本的 code 時,會發生 error ,需要打開某幾個 config。 vendor t ...
  • 校對規則:在當前編碼下,字元之間的比較順序。(cs大小寫敏感,ci大小寫不敏感,bin二進位編碼比較) 1. 查看當前校對規則 show collation; 每個字元集都支持不定數量的校對規則,下圖為查看結果的部分截圖: tip : 以big5_chinese_ci為例,其中big5表示字元集,c ...
  • 首先下載instantclient,可自行搜索引擎搜索下載。 下載完成解壓後 找到解壓的文件目錄下的network\admin路徑下的tnsnames.ora 文件 比如我解壓在c盤根目錄,那麼在C:\instantclient_11_2\network\admin在此路徑中找到tnsnames.o ...
  • 1、基礎環境說明 虛擬機:VMWare 操作系統:linux 資料庫版本:mysql 5.7.13 社區版(別問為什麼不裝企業版,因為企業版要錢) 背景:虛擬機可以連上外網 2、摸底 查看linux上是否已經安裝了mysql ① 啟動服務 service mysqld start 沒有安裝,則提示 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...