.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
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...