石家莊網(wǎng)站建設(shè)模板服務(wù)臨沂seo建站
第一次做Oracle項目的時候?qū)σ恍┱Z法區(qū)別不太清楚,這里列出一些開發(fā)中發(fā)現(xiàn)的與MYSQL不同的點
-
一個用戶相當于一個數(shù)據(jù)庫
-
表空間
表空間是用于存儲表、索引和其他數(shù)據(jù)庫對象的邏輯存儲結(jié)構(gòu)。每個表空間由一個或多個數(shù)據(jù)文件組成,這些文件可以位于不同的物理磁盤上。
CREATE TABLESPACE example_tbs DATAFILE '/u01/app/oracle/oradata/example/example01.dbf' SIZE 100M AUTOEXTEND ON NEXT 50M MAXSIZE 500M;
-
修改列名的語法
--oracle ALTER TABLE table_name RENAME COLUMN old_column_name TO new_column_name; --mysql ALTER TABLE table_name CHANGE COLUMN old_column_name new_column_name datatype;
-
sysydate 表示當前日期
-
在Oracle數(shù)據(jù)庫中,ROWID 是一個偽列,用于標識表中的行。每個 ROWID 可以用于快速定位表中的行。
ROWID 值是一個字符串,由以下三個部分組成:
數(shù)據(jù)對象的編號(Data Object Number,也稱為文件標識符)
數(shù)據(jù)塊的編號(Data Block Number)
在數(shù)據(jù)塊中的行號(Row Number)
例如,以下 ROWID 值表示 employees 表中的一行:AAAR3zAAEAAAAVvAAA
其中,前六個字符 AAAR3z 是數(shù)據(jù)對象的編號,接下來的六個字符 AAEAAA 是數(shù)據(jù)塊的編號,最后的三個字符 VVAAA 是在數(shù)據(jù)塊中的行號。
ROWID 值是基于物理存儲結(jié)構(gòu)計算的,并且可能會因為表的重建、分區(qū)或其他操作而發(fā)生變化。因此,在使用 ROWID 時需要格外小心,并且盡可能使用其他方法來定位表中的行。
-
在 Oracle 數(shù)據(jù)庫中,ROWNUM 是一個偽列,用于給查詢結(jié)果中的行分配行號。ROWNUM 的值是一個整數(shù),從 1 開始遞增,表示查詢結(jié)果中的第幾行。
以下是使用 ROWNUM 的基本語法:
SELECT ROWNUM, employee_id, first_name, last_name FROM employees WHERE ROWNUM <= 10;
返回名為 employees 表中前 10 行數(shù)據(jù),并為每行分配一個行號
需要注意的是,ROWNUM 是在查詢結(jié)果返回之后才分配的行號,因此不能在查詢過程中使用它來篩選數(shù)據(jù)。例如,以下查詢不會返回任何數(shù)據(jù):
SELECT ROWNUM, employee_id, first_name, last_name FROM employees WHERE ROWNUM > 10;
這是因為 ROWNUM 的值在結(jié)果返回之前就已經(jīng)被計算了,而 WHERE 子句只能篩選已經(jīng)返回的結(jié)果。如果要篩選結(jié)果集中的行號,可以使用子查詢或通用表表達式(CTE)等方法。
第 11 到 20 行數(shù)據(jù) SELECT * FROM (SELECT t.*, ROWNUM rnFROM my_table tWHERE ROWNUM <= 20 ) WHERE rn >= 11; 按照id升序排序后獲取第 11 到 20 行數(shù)據(jù) SELECT * FROM (SELECT t.*, ROWNUM rnFROM (SELECT *FROM my_tableORDER BY id) tWHERE ROWNUM <= 20 ) WHERE rn >= 11;```
-
NVL 函數(shù)接受兩個參數(shù),如果第一個參數(shù)不為空,則返回第一個參數(shù)的值;否則返回第二個參數(shù)的值。
SELECT NVL(name, 'N/A') AS name, NVL(age, 0) AS age FROM my_table;
NVL2 函數(shù)接受三個參數(shù),如果第一個參數(shù)不為空,則返回第二個參數(shù)的值;否則返回第三個參數(shù)的值。
SELECT NVL2(name, 'Name is not empty', 'Name is empty') AS result FROM my_table;
-
DECODE 函數(shù)接受多個參數(shù),第一個參數(shù)是要比較的字段或表達式,后面的參數(shù)是一組值和對應(yīng)的結(jié)果。如果要比較的字段或表達式等于某個值,則返回該值對應(yīng)的結(jié)果;否則返回最后一個參數(shù)作為默認結(jié)果。
SELECT DECODE(gender, 'M', 'Male', 'F', 'Female', 'Unknown') AS result FROM my_table; =============== 如果 gender 字段等于 'M',則返回字符串 "Male";如果 gender 字段等于 'F',則返回字符串 "Female";否則返回字符串 "Unknown"。
-
CASE 表達式根據(jù) gender 字段的值,在查詢結(jié)果中添加一個名為 gender_desc 的新列。如果 gender 字段等于 ‘M’,則返回字符串 “Male”;如果 gender 字段等于 ‘F’,則返回字符串 “Female”;否則返回字符串 “Unknown”。
SELECT name, age, gender,CASE genderWHEN 'M' THEN 'Male'WHEN 'F' THEN 'Female'ELSE 'Unknown'END AS gender_desc FROM my_table;
-
SELECT name, score, RANK() OVER (ORDER BY score DESC) AS rank FROM my_table;
RANK() 函數(shù)根據(jù) score 字段的值為每個行分配一個排名,并將排名保存在名為 rank 的新列中。ORDER BY 子句指定了按照 score 字段的值降序排序。如果有多個行具有相同的值,則它們將被分配相同的排名,并且下一個排名將被跳過。dense_rank()則連續(xù),row_number()連續(xù)排名無論值是否相同。
-
視圖
CREATE [OR REPLACE] VIEW view_name [(column1, column2, ...)] AS SELECT statement;
CREATE VIEW 用于創(chuàng)建一個新的視圖,OR REPLACE 用于替換一個已經(jīng)存在的同名視圖(如果存在),view_name 是視圖的名稱,column1, column2, … 是視圖中包含的列名,SELECT statement 是用于創(chuàng)建視圖的查詢語句。
需要注意的是,在 Oracle 數(shù)據(jù)庫中,視圖可以包含復(fù)雜的查詢和窗口函數(shù)等高級特性,而在 MySQL 數(shù)據(jù)庫中,視圖的功能相對較為簡單。此外,在 Oracle 數(shù)據(jù)庫中,視圖可以使用 WITH CHECK OPTION 子句來限制對視圖的修改操作;而在 MySQL 數(shù)據(jù)庫中,視圖不支持 WITH CHECK OPTION 子句。
視圖和表的數(shù)據(jù)是相互綁定的。修改視圖數(shù)據(jù)時只會影響鍵保留表里的數(shù)據(jù),也就是主鍵來自的那張表。
-
物化視圖:物化視圖是一個包含了預(yù)先計算好的數(shù)據(jù)的表,這些數(shù)據(jù)可以是聚合數(shù)據(jù)、連接查詢或者其他復(fù)雜查詢的結(jié)果。當查詢需要訪問這些數(shù)據(jù)時,數(shù)據(jù)庫可以直接從物化視圖中讀取數(shù)據(jù),而不必重新計算查詢結(jié)果。
CREATE MATERIALIZED VIEW view_name BUILD [IMMEDIATE|DEFERRED] REFRESH [FAST|COMPLETE|FORCE] [START WITH date] [NEXT date] [on commit] AS SELECT statement [LOGGING;]手動刷新 begin EXEC DBMS_SNAPSHOT.REFRESH('my_view', 'C'); end;
CREATE MATERIALIZED VIEW 用于創(chuàng)建一個新的物化視圖,BUILD IMMEDIATE 或 BUILD DEFERRED 用于指定何時開始構(gòu)建物化視圖,REFRESH FAST、REFRESH COMPLETE 或 REFRESH FORCE 用于指定何時刷新物化視圖,START WITH 和 NEXT 用于指定刷新計劃,view_name 是物化視圖的名稱,SELECT statement 是用于創(chuàng)建物化視圖的查詢語句。LOGGING 選項表示啟用日志記錄功能,用于記錄增量數(shù)據(jù)
在 MySQL 數(shù)據(jù)庫中,創(chuàng)建物化視圖的語法與普通視圖類似,但是 MySQL 不支持像 Oracle 那樣的 REFRESH 選項和 START WITH/NEXT 選項。
-
序列:
CREATE SEQUENCE my_seq START WITH 1 INCREMENT BY 1 MAXVALUE 999999999 NOCACHE NOORDER;
my_seq 是序列的名稱,START WITH 1 表示起始值為 1,INCREMENT BY 1 表示遞增量為 1,MAXVALUE 999999999 表示最大值為 999999999,NOCACHE 表示不緩存序列值,NOORDER 表示不保證序列值的順序。
需要注意的是,序列是數(shù)據(jù)庫級別的對象,可以被多個表共享。
-
在MySQL中,用戶定義變量只在當前會話中有效。而在Oracle中,PL/SQL變量的作用域可以是整個程序或子程序。
--mysql SET @my_var = 10; SELECT CONCAT('My variable is ', @my_var);--oracle DECLAREmy_var NUMBER; BEGINmy_var := 10;DBMS_OUTPUT.PUT_LINE('My variable is ' || my_var); END; --如果不知道v_last_name數(shù)據(jù)類型但知道其來源列 DECLAREv_last_name employees.last_name%TYPE; BEGINSELECT last_name INTO v_last_name FROM employees WHERE employee_id = 100;DBMS_OUTPUT.PUT_LINE('The last name is ' || v_last_name); END; --如果不知道v_employee數(shù)據(jù)類型但知道其來源行 DECLAREv_employee employees%ROWTYPE; BEGINSELECT * INTO v_employee FROM employees WHERE employee_id = 100;DBMS_OUTPUT.PUT_LINE('The employee name is ' || v_employee.first_name || ' ' || v_employee.last_name); END;
-
異常處理
BEGIN-- 此處是正常的 PL/SQL 代碼... EXCEPTIONWHEN exception1 THEN-- 異常處理代碼1...WHEN exception2 THEN-- 異常處理代碼2... END; ============================================================ BEGINSELECT column1 INTO variable1 FROM table1 WHERE column2 = value;EXCEPTIONWHEN NO_DATA_FOUND THEN-- 處理 No Data Found 異常variable1 := NULL; END;
-
循環(huán)
--oracle FOR i IN 1..10 LOOP-- 執(zhí)行循環(huán)體中的代碼 END LOOP;WHILE condition LOOP-- 執(zhí)行循環(huán)體中的代碼 END LOOP;
-
分區(qū),可以把表根據(jù)某種規(guī)則分區(qū),插入數(shù)據(jù)時無感知。查詢可以根據(jù)分區(qū)的規(guī)則查詢
CREATE TABLE SALES (SALES_ID NUMBER,SALE_DATE DATE,CUSTOMER_ID NUMBER,PRODUCT_ID NUMBER,AMOUNT NUMBER ) PARTITION BY RANGE (SALE_DATE) (PARTITION SALES_Q1 VALUES LESS THAN (TO_DATE('01-APR-2023', 'DD-MON-YYYY')),PARTITION SALES_Q2 VALUES LESS THAN (TO_DATE('01-JUL-2023', 'DD-MON-YYYY')),PARTITION SALES_Q3 VALUES LESS THAN (TO_DATE('01-OCT-2023', 'DD-MON-YYYY')),PARTITION SALES_Q4 VALUES LESS THAN (TO_DATE('01-JAN-2024', 'DD-MON-YYYY')) );SELECT * FROM SALES PARTITION (SALES_Q1); SELECT * FROM SALES PARTITION (SALES_Q2); SELECT * FROM SALES PARTITION (SALES_Q3); SELECT * FROM SALES PARTITION (SALES_Q4);