程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> Oracle Pro*C 動態SQL技術

Oracle Pro*C 動態SQL技術

編輯:Oracle數據庫基礎

Pro*C的常用動態SQL技術一共有3種:

  1. 用於處理不包含宿主變量的動態SQL, 不能用於SELECT語句.
  2. 用於處理輸入宿主變量個數和類型已經確定的動態SQL, 不能用於SELECT語句.
  3. 用於處理選擇列表項和輸入宿主變量個數已經確定的動態SQL, 此種方法可以處理所有前兩種方法能處理的情況, 此外, 還能處理SELECT語句.

由於第3種方法已經包含前兩種方法的處理范圍, 這篇文章我們主要介紹第3種方法.

1 介紹:

1.1 適用語句:

  • DML(Data Manipulation Language 數據操縱語言)
  • DDL(Data Definition Language 數據定義語言)
  • DCL(Data Control Language 數據控制語言)
  • 以及事務控制語句
  • 而且還可以處理SELECT語句 

   用SQL語句舉例就是:

  • DELETE FROM tbl_name WHERE name=xxx
  • CREATE TABLE tbl_name(cola INT)
  • GRANT SELECT ON xx TO xxx
  • COMMIT
  • INSERT INTO tbl_name VALUES(:a)
  • DELETE FROM tbl_name WHERE name=:a
  • SELECT name FROM tbl_name WHERE no=xxx

1.2 不能處理的語句:

總體來講就是對象名和列名不能使用宿主變量, 例如:

  • INSERT INTO :a VALUES(:b)
  • SELECT :a, :b FROM tbl_name WHERE name=:c

2 處理步驟:

2.1 PREPARE語句:

PREPARE命令用於明明和解析SQL語句, 語法如下:



EXEC SQL PREPARE statement_name
    FROM {:host_string | string_literal};

說明:

  • statement_name: 預編譯器標識符.
  • host_string: 包含SQL語句的宿主變量.
  • string_literal: SQL語句文本字符串.

2.2 DECLARE游標:

使用PREPARE准備了SQL語句之後, 應該執行內嵌DECLARE命令定義游標, 語法如下:



EXEC SQL DECLARE cursor_name CURSOR
    FOR statement_name;

說明:

  • cursor_name: 游標名.
  • statement_name: statement標識符, 在PREPARE過程中使用的.

2.3 OPEN打開游標:

當開始游標時, 會執行游標所對應的SQL語句, 語法如下:



EXEC SQL OPEN cursor_name [USING host_variable_list];

說明:

  • cursor_name: 游標名, 前面DECLARE的.
  • host_variable_list: 輸入的宿主變量列表.

當執行OPEN命令時, 如果SQL語句不是SELECT語句, 會直接執行該語句, 此後可以關閉游標; 如果SQL語句是SELECT語句, 那麼會將查詢結果放到游標結果集中, 還必須使用內嵌的FETCH語句提取並處理游標結果集, 之後再關閉游標.

2.4 FETCH提取游標數據:

當SQL語句是SELECT語句時, OPEN之後會把結果存放到游標結果集中, 為了處理查詢結果, 需要使用FETCH來提取數據, 語法如下:



EXEC SQL FETCH cursor_name INTO host_variable_list;

說明:

cursor_name: 游標名, 前面OPEN的.

host_variable_list: 輸入的宿主變量列表.

2.5 CLOSE關閉游標:

提取並處理完游標數據後, 關閉游標, 語法如下:



EXEC SQL CLOSE cursor_name;

3 代碼舉例:



/* 大組成員表結構 */
struct GrpMember
{
    char str_bgID[22];  /* 大組ID */

    char str_matID[22]; /* 素材ID */
    ...
    ...
};
/*
*
 * 素材檢索
 * 填沖好一個輸入結構, 作為函數的參數進行調用.
 *
 * 這個輸入結構中的各各成員項可以為空, 
 * 通過判斷來確定數據庫檢索條件, 即: SELECT語句後面的條件.
 *
 */

void MatSearch(struct GrpMember *in)
{
    /* 定義臨時變量 */

    char buf[256]; /* buffer */

    /* 定義宿主變量 */
    EXEC SQL BEGIN DECLARE SECTION;
        
char sql_buf[1024]; /* 存放SQL語句 */
        struct GrpMember ret; /* 查詢結果 */
    EXEC SQL END DECLARE SECTION;

    
/*
     * 根據參數, 構造SQL語句
     *
     * 1 把SQL語句的前半部分拷貝到buffer中.
     * 2 判斷輸入參數的結構中各成員項是否為空, 如不為空, 則add到buffer中.
     */

    strcpy(sql_buf, "SELECT * FROM TBL_GRPMEMBER WHERE 1=1 ");
    if (!
isEmpty(str_bgID))
    {
        sprintf(buf, "AND tbl_str_bgID = %s "
, str_bgID);
        strcat(sql_buf, buf);
    }
    ...
    ...

    /* 准備動態SQL */

    EXEC SQL PREPARE sql_stmt FROM :sql_buf;

    
/* 定義游標 */
    EXEC SQL DECLARE c1 CURSOR FOR sql_stmt;

    
/* 打開游標: 執行查詢 */
    EXEC SQL OPEN c1;

    
/* 提取查詢結果 */
    while(1)
    {
        EXEC SQL FETCH c1 INTO ret; /* 此處偽代碼, 應該逐項INTO, 逗號分割, 具體見游標的使用 */

    }

    EXEC SQL CLOSE c1;
}



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved