The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何快速建立 Oracle Database Server 12c R2 資料庫容器並建立使用者

最近越來越多 ASP.NET Core 企業內訓需求,有客戶提到希望能在上課的時候展示 Entity Framework Core 與 Oracle 資料庫的整合能力,我第一時間就想到要在本機安裝 Oracle 資料庫容器起來,快速建立可開發測試的環境。不過,雖然建立 Oracle 資料庫容器相當簡單方便,但不太熟悉 Oracle 資料庫特性的我,卻連第一步「建立使用者」都沒辦法成功,錯誤訊息也相當難以理解,花了一些時間才找到解決之道。


這篇文章已經過時,請移駕 如何在 Windows 快速啟動一個 Oracle Database 23c Free 資料庫容器 觀看最新版文章。


執行 Oracle Database Server 12c R2 容器

要在本機執行 Docker 容器之前,請先參考 Install Docker Desktop on Windows 文件進行 Docker 安裝。

由於 Oracle 官方提供的 Oracle Database Server 12c R2 image 放在 Docker Hub 上面,而且必須先登入 Docker Store 才能下載,所以在執行容器之前,必須先用 docker 命令進行登入:

docker login

只要登入完成,就可以進行 docker pull 下載 Oracle 授權的容器映像 (Container images),目前官方提供兩個版本:

  1. Oracle Database Server 12.2.0.1 Enterprise Edition (完整版)
  2. Oracle Database Server 12.2.0.1 Enterprise Edition Slim Variant (精簡版)
docker pull store/oracle/database-enterprise:12.2.0.1
docker pull store/oracle/database-enterprise:12.2.0.1-slim

如果你只想測試簡單的資料庫功能,建議安裝 Slim Variant 版本即可,不但 image 體積小,啟動速度也較快。

接著就直接執行容器,大約 1 ~ 2 分鐘才會啟動完畢:

docker run -d -it --name oracle -p 1521:1521 -p 5500:5500 store/oracle/database-enterprise:12.2.0.1-slim

如果你希望保留本次容器執行所建立的資料庫,可以透過 docker volume mapping 做到:

docker volume create OracleDBData

docker run -d -it --name oracle -p 1521:1521 -p 5500:5500 -v OracleDBData:/ORCL store/oracle/database-enterprise:12.2.0.1-slim

官方容器的預設帳號密碼如下:

  • SID:ORCLCDB
  • 帳號:SYS
  • 密碼:Oradoc_db1

如果不從外部連線的話,可以直接透過 docker exec 命令從 Oracle 容器中執行 sqlplus 工具:

docker exec -it oracle bash -c "source /home/oracle/.bashrc; sqlplus /nolog"

接著可以透過以下 SQL 命令登入 SYSSYSDBA 角色:

CONNECT SYS/Oradoc_db1 AS SYSDBA;

或是直接在執行 sqlplus 時就直接登入:

docker exec -it oracle bash -c "source /home/oracle/.bashrc; sqlplus sys/Oradoc_db1@ORCLCDB as sysdba"

建議第一次登入就先修改 SYS 預設密碼,請參考以下命令進行修改:ALTER USER SYS IDENTIFIED BY <new-password>;

登入後,可以透過以下 SQL 命令,查詢目前資料庫的服務名稱(ORCLCDB.localdomain):

SELECT VALUE FROM V$PARAMETER WHERE NAME='service_names';

如果要透過 Oracle SQL Developer 登入,可以參考以下截圖進行設定:

建立使用者

當 Oracle 容器完全啟動之後,悲劇也就開始發生了,因為我連一個使用者都無法建立!

因為 Oracle 資料庫跑在容器中,有著不同的安全性架構,從 Oracle 12cR1 開始,因為新增了多租戶架構(multitenant architecture),可以讓你在一個資料庫容器中執行多個租戶資料庫(tenant databases),所以建立使用者的 SQL 命令稍微有點不一樣,而這個問題對一個不常使用 Oracle 的開發者來說也太困難了。

如果你用傳統的 SQL 命令建立一個新用戶,就會得到這個錯誤:ORA-65096: invalid common user or role name

SQL> CREATE USER WILL IDENTIFIED BY yourpassword;
CREATE USER WILL IDENTIFIED BY yourpassword
            *
ERROR at line 1:
ORA-65096: invalid common user or role name

而正確建立使用者的方法,應該用以下 SQL 命令:

ALTER SESSION SET "_ORACLE_SCRIPT"=TRUE;
CREATE USER will IDENTIFIED BY yourpassword;
GRANT CONNECT, RESOURCE, DBA TO WILL;
ALTER SESSION SET "_ORACLE_SCRIPT"=FALSE;

接著就可以用新帳號登入連線:

CONNECT WILL/yourpassword AS SYSDBA;

刪除使用者

基本上,只要跟「使用者」相關的操作,在 Oracle 容器中都會遇到問題,所以若要刪除上一節所建立的 WILL 帳號的話,必須使用以下 SQL 命令:

ALTER SESSION SET "_ORACLE_SCRIPT"=TRUE;
DROP USER WILL CASCADE;
ALTER SESSION SET "_ORACLE_SCRIPT"=FALSE;

建立範例資料庫

我從 Getting Started with Oracle Database 找到一個 Oracle Sample Database 非常適合用來學習與測試 Oracle 資料庫連線,以下我將用這個範例進行解說。

下載範例資料庫之後,你將會看到四個檔案:

  1. ot_create_user.sql

    你首先要解決的困難就是將 ot_create_user.sql 稍微修改一下,前後都加上 ALTER SESSION 命令:

    ALTER SESSION SET "_ORACLE_SCRIPT"=TRUE;
    
    -- create new user
    CREATE USER OT IDENTIFIED BY yourpassword;
    -- grant priviledges
    GRANT CONNECT, RESOURCE, DBA TO OT;
    
    ALTER SESSION SET "_ORACLE_SCRIPT"=FALSE;
    
  2. ot_schema.sql

    建立 Schema 時並不會發生問題。

    建立好之後,可以透過 SELECT table_name FROM user_tables; 密令列出所有建立的表格。(參考)

  3. ot_data.sql

    匯入資料時,你會遇到 ORA-01843: 不是有效的月份 錯誤,那是因為這個範例資料的 SQL 語法,使用的是美國的日期表示法,你必須在匯入資料前,先執行以下 SQL 才可以成功匯入所有資料:

    ALTER SESSION SET NLS_DATE_LANGUAGE='american';
    
  4. ot_drop.sql

    等測試完成後,就可以執行這個 SQL 檔案,刪除所有表格。

    如果想刪除 OT 使用者,請記得手動刪除。

同場加映:透過 Oracle.EntityFrameworkCore 產生 EFCore 實體模型

dotnet add package Oracle.EntityFrameworkCore

dotnet ef dbcontext scaffold "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCLCDB.localdomain)));User Id=OT;Password=yourpassword;" Oracle.EntityFrameworkCore -o Models

上述 Oracle 連接字串的 Data Source 部分,可以透過 docker logs oracle 查詢相對應的提示訊息

相關連結

留言評論