首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 開發實戰技巧彙總:SEQUENCE 更新、CASE 語句、Pro*C 編譯、C++ 互操作

     編輯:Oracle 資料庫相關知識

SQL 技巧

1. UPDATE 搭配 SEQUENCE 批次編號


-- 為現有資料補上連續流水號
UPDATE sample SET id = seq_id.NEXTVAL;

-- 條件式更新
UPDATE sample 
SET seq_no = seq_id.NEXTVAL
WHERE status = 'PENDING'
AND seq_no IS NULL;

優點:單一 SQL 完成,無需游標迴圈,效能極佳。

2. SELECT 中使用 CASE 運算式


-- 簡單 CASE
SELECT col1,
       CASE col1 WHEN 1 THEN 'One' WHEN 2 THEN 'Two' ELSE 'Other' END AS col2
FROM tab;

-- 搜尋 CASE (支援複雜條件)
SELECT col1,
       CASE 
         WHEN col1 > 100 THEN 'High'
         WHEN col1 > 50 THEN 'Medium'
         ELSE 'Low'
       END AS level
FROM tab;

-- 聚合中使用
SELECT deptno,
       SUM(CASE WHEN sal > 3000 THEN 1 ELSE 0 END) AS high_sal_cnt,
       SUM(CASE WHEN sal <= 3000 THEN 1 ELSE 0 END) AS low_sal_cnt
FROM emp
GROUP BY deptno;

Pro*C/C++ 預編譯與建置

預編譯指令


# 基本編譯
proc iname=file.pc oname=file.c

# 多執行緒支援
proc iname=file.pc oname=file.c threads=yes

# 指定字元集
proc iname=file.pc oname=file.c charset=utf8

# 包含路徑
proc iname=file.pc oname=file.c include=$ORACLE_HOME/precomp/public

編譯鏈結 (Linux/GCC)


# 1. Pro*C 預編譯
proc iname=myapp.pc oname=myapp.c threads=yes

# 2. 編譯 C 產生目標檔
gcc -c -I$ORACLE_HOME/precomp/public -I$ORACLE_HOME/rdbms/public myapp.c -o myapp.o

# 3. 鏈結建立執行檔
gcc myapp.o -o myapp -L$ORACLE_HOME/lib -lclntsh

# 執行前設定 core dump
ulimit -c unlimited

# 除錯
gdb myapp core.9959

關鍵庫與路徑

項目路徑/名稱
Pro*C 可執行檔$ORACLE_HOME/bin/proc
預編譯公共頭檔$ORACLE_HOME/precomp/public
RDBMS 公共頭檔$ORACLE_HOME/rdbms/public
客戶端共享庫libclntsh.so (或 .sl/.dll)
庫路徑$ORACLE_HOME/lib
執行期庫路徑環境變數LD_LIBRARY_PATH (Linux)、PATH (Windows)

C/C++ 型別轉換與字串處理

std::string 與 C 風格字串互轉


// string -> const char* (唯讀)
const std::string str = "hello";
const char* cstr = str.c_str();  // 指向內部緩衝區,str 銷毀前有效

// string -> char* (可修改,需複製)
std::string str = "hello";
char* mutable_cstr = new char[str.length() + 1];
std::strcpy(mutable_cstr, str.c_str());
// 使用後 delete[] mutable_cstr;

// char* -> string
const char* cstr = "world";
std::string str(cstr);  // 或 string str = cstr;

// 格式化字串 (C++11+)
#include 
std::ostringstream oss;
oss << "ID: " << id << ", Name: " << name;
std::string formatted = oss.str();

// C++20 std::format
std::string formatted = std::format("ID: {}, Name: {}", id, name);

空值檢查慣用寫法


// std::string
std::string str;
if (str.empty()) { /* 空字串 */ }
if (!str.empty()) { /* 非空 */ }

// 原始指標
char* ptr = nullptr;
if (ptr == nullptr) { /* 空指標 */ }
if (ptr != nullptr) { /* 非空 */ }

// 智慧指標 (C++11+)
std::unique_ptr uptr;
if (uptr) { /* 非空 */ }
std::shared_ptr sptr;
if (sptr) { /* 非空 */ }

Oracle OCI 型別對應

Oracle 型別C/C++ 型別OCI 定義
NUMBEROCINumber / double / longOCINumberToReal / OCINumberFromInt
VARCHAR2char* / std::stringSQLT_CHR / SQLT_STR
DATEOCIDateOCIDateToText / OCIDateFromText
TIMESTAMPOCIDateTimeOCIDateTimeConstruct
RAWunsigned char* / OCIRawSQLT_BIN
BLOB/CLOBOCILobLocator*OCILobRead / OCILobWrite
ROWIDOCIRowid*SQLT_RDD

常見 Pro*C 錯誤與解決

錯誤原因解決
PCC-S-02015: unable to open include file頭檔路徑錯誤檢查 include= 參數、環境變數
PCC-F-02102: fatal error語法錯誤、EXEC SQL 區塊未閉合檢查 .pc 原始碼、分號、大括號
undefined reference to sqlcxt鏈結缺少 libclntsh-L$ORACLE_HOME/lib -lclntsh
ORA-24756: transaction does not existCOMMIT/ROLLBACK 不配對檢查 EXEC SQL COMMIT/ROLLBACK 邏輯
Segmentation fault指標未初始化、緩衝區溢位啟用 core dump、gdb 除錯、valgrind 檢測

效能調優提醒

  • 使用 ARRAY FETCH (Pro*C EXEC SQL FETCH ... FOR :n ROWS) 減少網路往返
  • 批次 INSERT/UPDATE/DELETE 使用 FOR :n ROWS 陣列操作
  • 預編譯選項 RELEASE_CURSOR=YES、HOLD_CURSOR=NO 釋放游標資源
  • 啟用 THREADS=YES 支援多執行緒連線池
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved