0. 前言
由於目前的專案採用 Oracle, 且整個資料庫是由客戶的 DBA 在管理, 為了安全上的考量, 在存取客戶現行使用者的資料表時, 只會提供廠商新的使用者帳號及密碼, 而不會提供現行使用者的帳號及密碼.
舉例而言, 假設 table: T2 由客戶的 USER2 所建立, 而客戶提供給廠商的使用者為 USER1; 雖然客戶已將 USER2.T2 這個 table 的權限開放給 USER1, 當然可以採用 USER2.T2 去存取.
但這樣會造成 參考文件1 提到的狀況:
- 每次使用用 Table 時都要加上 "USER2.".
- 程式碼寫死了 Schema 名稱, 一旦Schema名稱調整, 將有改不完的程式.
在網路上查了一下, 看來應該可以透過 Synonym (別名) 的方式來處理. Synonym 的用途如下:
- 主要用在縮短資料庫物件 (table, view, sequence or program unit) 的名稱, 不需實際指定 schema.
- 亦可用在如上述的資安議題.
以下茲分幾個步驟, 進行狀況模擬實測:
1. STEP 1: 客戶 DBA 的工作: 建立 Table Space
建立 TBS_USER1 及 TBS_USER2, 供模擬測試用.
-- =================================
-- TABLE SPACES
-- =================================
-- 查詢異動前的 Tablespace, 結果如 [圖1]
SELECT TABLESPACE_NAME, FILE_NAME, bytes / 1024/ 1024 MB FROM DBA_DATA_FILES;
-- 建立各個 TABLE SPACES
-- DROP TABLESPACE TBS_USER1 INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS;
CREATE TABLESPACE TBS_USER1
DATAFILE 'D:\APP\ADMINISTRATOR\ORADATA\MYDB\DATAFILE\TBS_USER1_FILE01.DBF'
SIZE 20M AUTOEXTEND ON;
-- DROP TABLESPACE TBS_USER2 INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS;
CREATE TABLESPACE TBS_USER2
DATAFILE 'D:\APP\ADMINISTRATOR\ORADATA\MYDB\DATAFILE\TBS_USER2_FILE01.DBF'
SIZE 20M AUTOEXTEND ON;
-- 查詢異動後的 Tablespace, 結果如 [圖2]
SELECT TABLESPACE_NAME, FILE_NAME, bytes / 1024/ 1024 MB FROM DBA_DATA_FILES;
-- ==============
-- 預期結果
-- ==============
/*
TABLESPACE_NAME FILE_NAME MB
------------------- -------------------------------------------------------------------------- -------
SYSTEM D:\APP\ADMINISTRATOR\ORADATA\MYDB\DATAFILE\O1_MF_SYSTEM_HWCSDHM4_.DBF 890
SYSAUX D:\APP\ADMINISTRATOR\ORADATA\MYDB\DATAFILE\O1_MF_SYSAUX_HWCSGGRZ_.DBF 500
USERS D:\APP\ADMINISTRATOR\ORADATA\MYDB\DATAFILE\O1_MF_USERS_HWCSJCSH_.DBF 5
UNDOTBS1 D:\APP\ADMINISTRATOR\ORADATA\MYDB\DATAFILE\O1_MF_UNDOTBS1_HWCSHZG8_.DBF 65
4 個資料列已選取.
TABLESPACE TBS_USER1 已建立.
TABLESPACE TBS_USER2 已建立.
TABLESPACE_NAME FILE_NAME MB
------------------- -------------------------------------------------------------------------- -------
SYSTEM D:\APP\ADMINISTRATOR\ORADATA\MYDB\DATAFILE\O1_MF_SYSTEM_HWCSDHM4_.DBF 890
SYSAUX D:\APP\ADMINISTRATOR\ORADATA\MYDB\DATAFILE\O1_MF_SYSAUX_HWCSGGRZ_.DBF 500
TBS_USER1 D:\APP\ADMINISTRATOR\ORADATA\MYDB\DATAFILE\TBS_USER1_FILE01.DBF 20
USERS D:\APP\ADMINISTRATOR\ORADATA\MYDB\DATAFILE\O1_MF_USERS_HWCSJCSH_.DBF 5
TBS_USER2 D:\APP\ADMINISTRATOR\ORADATA\MYDB\DATAFILE\TBS_USER2_FILE01.DBF 20
UNDOTBS1 D:\APP\ADMINISTRATOR\ORADATA\MYDB\DATAFILE\O1_MF_UNDOTBS1_HWCSHZG8_.DBF 65
6 個資料列已選取.
*/
2. STEP 2: 客戶 DBA 的工作: 建立使用者及權限
加入使用者, 並賦與權限 (USER1, USER2).
-- =================================
-- USERS
-- =================================
-- DROP USER USER1 CASCADE;
CREATE USER USER1 IDENTIFIED BY USER1 DEFAULT TABLESPACE TBS_USER1 QUOTA UNLIMITED ON TBS_USER1;
GRANT CONNECT,RESOURCE TO USER1;
GRANT CREATE ANY SYNONYM TO USER1;
-- DROP USER USER2 CASCADE;
CREATE USER USER2 IDENTIFIED BY USER2 DEFAULT TABLESPACE TBS_USER2 QUOTA UNLIMITED ON TBS_USER2;
GRANT CONNECT,RESOURCE TO USER2;
GRANT CREATE ANY SYNONYM TO USER2;
-- ==============
-- 預期結果
-- ==============
/*
User USER1 已建立.
Grant 成功.
Grant 成功.
User USER2 已建立.
Grant 成功.
Grant 成功.
*/
3. STEP 3: 客戶 USER2 的工作: 建立 Table
由 USER2 建立 table: T2, 並授權給 USER1 使用.
-- =================
-- 建立表格
-- =================
-- DROP TABLE T1;
CREATE TABLE T2(
C_ID INT GENERATED ALWAYS AS IDENTITY,
C_UID VARCHAR2(32),
C_NAME VARCHAR2(50)
) ;
-- =================
-- 新增資料
-- =================
INSERT INTO T2(C_UID, C_NAME)
VALUES(SYS_GUID(), 'JASPER');
COMMIT;
-- =================
-- GRANT table:T2 的權限
-- =================
GRANT SELECT, INSERT, UPDATE, DELETE
ON USER2.T2
TO USER1;
-- ==============
-- 預期結果
-- ==============
/*
Table T2 已建立.
1 資料列 已插入.
確認完成.
Grant 成功.
*/
4. STEP 4: 廠商 USER1 的工作: 建立 Synonym
由 USER1 建立對 USER2.T2 這個 table 的別名 (Synonym), 並進行存取.
-- =====================
-- 新增資料
-- =====================
INSERT INTO USER2.T2(C_UID, C_NAME)
VALUES(SYS_GUID(), 'JACK');
COMMIT;
-- =====================
-- 查詢資料
-- =====================
SELECT * FROM USER2.T2;
-- =====================
-- 雖然可以直接指定 schema name, 佰有沒有什麼其它的方式, 可以不用指定呢?
-- 方式1: View: 可以視為是 table or view 的重組
-- 方式2: Synonym: 可以視為是物件的別名, 例如: table, view, sequence or program unit
-- 這裡採用方式2, 且採用 PRIVATE SYNONYM
-- =====================
-- 這裡會發生權限不足的狀況, 要事先由 DBA 賦與權限
-- https://stackoverflow.com/questions/24830023/create-synonym-ora-01031-insufficient-privileges
-- GRANT CREATE ANY SYNONYM TO SYSCOM;
CREATE SYNONYM T2 FOR USER2.T2;
-- =====================
-- 新增資料
-- =====================
INSERT INTO T2(C_UID, C_NAME)
VALUES(SYS_GUID(), 'JASON');
COMMIT;
-- =====================
-- 查詢資料
-- =====================
SELECT * FROM T2;
-- ==============
-- 預期結果
-- ==============
/*
1 資料列 已插入.
確認完成.
C_ID C_UID C_NAME
---------- -------------------------------- --------------------------------------------------
1 7E62485357A04BFCB662DD72CD3AB75C JASPER
2 4F80105925A448C2B2CE434AF75215B4 JACK
Synonym T2 已建立.
1 資料列 已插入.
確認完成.
C_ID C_UID C_NAME
---------- -------------------------------- --------------------------------------------------
1 7E62485357A04BFCB662DD72CD3AB75C JASPER
2 4F80105925A448C2B2CE434AF75215B4 JACK
3 99494D08EF2D497DA90976CD6DC9900B JASON
*/
5. 結論
透過該專案, 增加了筆者對於 Oracle Synonym 的認識, 也算是一個收穫.
至於 參考文件1 所提 Oracle 版本的 Entity Framework 不支援 Synonym 的問題, 後續有時間, 再來試一下. 本專案主要以 Java 進行開發, 未採 Entity Framework, 筆者只是協助 ORACLE 資料庫的部份; 後續有時間再依 參考文件2, 3 來試試 C# 及 Entity Framework.
6. 參考文件
- 01. 黑暗執行緒, Entity Framework筆記:使用Oracle Synonym
- 02. 黑暗執行緒, 千呼萬喚始出來! Oracle官方版Entity Framework問市,邁入開發新時代
- 03. Yowko's Notes, 使用 Entity Framework 連線 Oracle - Database First
- 04. Oracle Help Center, SQL Language Reference: CREATE SYNONYM
- 05. StackOverflow, create synonym ora-01031 insufficient privileges


So well explained. I love to code in Java and I have compiled many Java programs in my life. This is the most sorted blog I have read about how to compile Java program. If you are a freelancer and looking for some challenging projects or high bid projects then sign up with Eiliana.com which is a global freelancing portal
回覆刪除