1. 程式人生 > >靜態SQL和動態SQL的區別和測試例項

靜態SQL和動態SQL的區別和測試例項

由於近期工作比較悠閒,所以就繼續學習了資料庫SQL的使用,實際工作中接觸最多的是SQL程式設計,那麼本博文就主要介紹動態sql和靜態sql的使用方法和區別,方便自己以後回憶和學習,如果本博文有幸被瀏覽者看到,如有瑕疵和錯誤還請幫忙指正,共同學習和進步。
所謂SQL的動態和靜態,是指SQL語句在何時被編譯和執行,二者都是用在SQL嵌入式程式設計中的。
靜態SQL:在高階語言中,如果嵌入了SQL語句,而這個SQL語句的主體結構已經明確,例如在c的一段程式碼中有一個待執行的SQL“select * from t1 where c1>5”,在編譯階段,就可以將這段SQL交給資料庫管理系統去分析,資料庫軟體可以對這段SQL進行語法解析,生成資料庫方面的可執行程式碼,這樣的SQL稱為靜態SQL,即在編譯階段就可以確定資料庫要做什麼事情。
動態SQL:如果嵌入的SQL沒有明確給出,如在c中定義了一個字元陣列型別的變數name:char name[32];,然後採用prepared Statement物件的execute方法去執行這個sql,該sql的值可能等於從文字框中讀取的一個SQL或者從鍵盤輸入的SQL,但具體是什麼,在編譯時無法確定,只有等到程式執行起來,在執行的過程中才能確定,這種SQL叫做動態SQL。例如每一種資料庫軟體都有能夠執行SQL語句的介面,那個介面接收的SQL就是動態SQL,因為資料庫廠商在做這個介面時,並不知道使用者會輸入哪些SQL,只有在該介面執行後,接收了使用者的實際輸入,才知道SQL是什麼。
注意:在SQL中如果某些引數沒有確定,如”select * from t1 where c1>? and c2

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

EXEC SQL INCLUDE SQLCA;
EXEC SQL INCLUDE SQLDA;
/*此函式屬於靜態SQL程式設計*/
int DBSelect_static(){
    EXEC SQL BEGIN DECLARE SECTION;
    char                _typename[32];
    short               _length;
    EXEC SQL END     DECLARE SECTION; 
    EXEC SQL  SELECT typename,length 
                        INTO :_typename,:_length
                        FROM syscat.columns 
                        WHERE tabname='SYSCOLUMNS'
and colname='DEFAULT'; printf("【typename:%s】【length:%d】\n",_typename,_length); } /*此函式屬於靜態SQL程式設計:指定函式引數作為SQL語句的變數*/ int DBSelect_static_param(char *tbl_str,char *col_str){ EXEC SQL BEGIN DECLARE SECTION; char _typename1[32]; short _length1; EXEC SQL END DECLARE SECTION; EXEC SQL SELECT typename,length INTO :_typename1,:_length1 FROM syscat.columns WHERE tabname='tbl_str'
and colname='col_str'; printf("【typename:%s】【length:%d】\n",_typename1,_length1); } /*此函式屬於動態SQL程式設計:SQL語句的結構是不確定的,需要根據使用者的輸入補全SQL語句*/ int DBUpdate_dynamic(){ EXEC SQL BEGIN DECLARE SECTION; char _address1[32]; char _tablename[32]; char _tmp[32]; char buf[256]; EXEC SQL END DECLARE SECTION; EXEC SQL SELECT count(address1) INTO :_tmp FROM cisaddressinfo WHERE customid='100000100000000000178'; if(0==_tmp) {printf("Not Found!\n");return -1;} memset(buf,0x00,sizeof(buf)); sprintf(buf,"update "); printf("Pls input : tablename ->"); scanf("%s",&_tablename); strcat(buf,_tablename); strcat(buf," set address1=? where customid='100000100000000000178'"); EXEC SQL PREPARE project FROM :buf; if(sqlca.sqlcode) perror("PREPARE"); printf("Pls input : address1 ->"); scanf("%s",&_address1); EXEC SQL EXECUTE project USING :_address1; if(sqlca.sqlcode) perror("EXECUTE"); EXEC SQL COMMIT WORK; if(sqlca.sqlcode) perror("COMMIT"); } /*此函式屬於動態SQL程式設計:使用sqlda資料結構組裝複雜多變的動態SQL*/ int DBSelect_dynamic(){ EXEC SQL BEGIN DECLARE SECTION; char hostVarStmt[256]; EXEC SQL END DECLARE SECTION; // 宣告兩個 SQLDA 指標,minsqlda 將是一個最小的 SQLDA 結構,用於 PREPARE 語句, // 此時結果集的欄位數量未知,所以只需一個最小的 SQLDA,即包含 HEADER 和一個 SQLVAR struct sqlda * minsqlda = (struct sqlda*)malloc(SQLDASIZE(1)); struct sqlda * fulsqlda = NULL; strcpy(hostVarStmt, "select WUID from workprocess where muid = '185001'"); // PREPARE 將填寫 minsqlda 的 header,sqldabc 為 SQLDA 總長度,sqln 為 SQLVAR 數量,即欄位數量 EXEC SQL PREPARE STMT INTO :*minsqlda FROM :hostVarStmt; // 根據從 minsqlda 中獲取的長度,分配完整的 SQLDA 結構 fulsqlda,其中將包括合適數量的 SQLVAR 結構 //結構sqlda的成員變數sqld返回select查詢語句的欄位的數目,可以根據此變數分配記憶體 fulsqlda = (struct sqlda *)malloc(SQLDASIZE(minsqlda->sqld)); // 使用 DESCRIBE 語句,獲取結果集中每個欄位的描述資訊,包括各欄位的型別 (sqltype) 和長度 (sqllen) EXEC SQL DESCRIBE STMT INTO :*fulsqlda; int i; for(i=0;i<minsqlda->sqld;i++) { // 根據每個欄位的長度,分配記憶體,將地址儲存在對應 SQLVAR 的 sqldata 中 // fulsqlda->sqlvar[i].sqldata=malloc(fulsqlda->sqlvar[i].sqllen); fulsqlda->sqlvar[i].sqldata=malloc(32); fulsqlda->sqlvar[i].sqlind=malloc(sizeof(short)); } // 宣告遊標 EXEC SQL DECLARE c1 CURSOR FOR STMT; EXEC SQL OPEN c1; EXEC SQL WHENEVER not found goto no_more_data; // 讀取記錄,記錄中每個欄位的內容將寫入 fulsqlda 中對應 SQLVAR 結構的 sqldata 指向的記憶體 // EXEC SQL FETCH c1 USING DESCRIPTOR :*fulsqlda; // 迴圈讀取所有記錄 for (;;) { EXEC SQL FETCH c1 USING DESCRIPTOR :*fulsqlda; for(i=0;i<minsqlda->sqld;i++){ printf("%d %s\n",fulsqlda->sqlvar[i].sqltype,fulsqlda->sqlvar[i].sqldata); usleep(10000); } } return 0; no_more_data: printf("\nEND of Data\n"); free(minsqlda); free(fulsqlda); EXEC SQL CLOSE c1; return 0; } int main(){ /*連線資料庫*/ EXEC SQL CONNECT TO ezeelink USER ezeelink USING EA704075ezeelink; DBSelect_static(); DBSelect_static_param("SYSCOLUMNS","DEFAULT"); DBUpdate_dynamic(); DBSelect_dynamic(); no_more_data: ; return 0; }

案例輸出結果如下:
【typename:VARCHAR】【length:254】
【typename:VARCHAR】【length:254】
Pls input : tablename ->cisaddressinfo
Pls input : address1 ->ShangHai
452 cis505
452 cis506
452 pub806
452 ips007
452 ips032
452 dps302

END of Data

注意:
如果使用動態SQL程式設計編寫select查詢語句並儲存結果,需要使用sqlda資料結構的,同時使用SQL的特性和功能,如:PREPARE ,EXECUTE ,DESCRIBE , DECLARE CURSE C1 FOR … , OPEN CURSE , CLOSE CURSE ….等等
建議:
動態SQL適用於表名及查詢欄位名未知的情況。在已知查詢欄位名及表名的情況下,使用動態SQL(字串拼接方式)會增加硬解析的開銷,在這種情況下,建議使用靜態SQL,這樣可以提高執行效率。在過程過程用拼湊的動態sql效率並不高,有時候還不如程式直接傳遞sql.靜態SQL是前置編譯繫結,動態SQL是後期執行時才編譯繫結

相關推薦

靜態SQL動態SQL區別測試例項

由於近期工作比較悠閒,所以就繼續學習了資料庫SQL的使用,實際工作中接觸最多的是SQL程式設計,那麼本博文就主要介紹動態sql和靜態sql的使用方法和區別,方便自己以後回憶和學習,如果本博文有幸被瀏覽者看到,如有瑕疵和錯誤還請幫忙指正,共同學習和進步。 所謂S

oracle靜態sql動態sql

收入 性能 varchar 建立 系統 根據 ora imm arch 1.靜態SQL與動態SQLOracle編譯PL/SQL程序塊分為兩個種:  其一為前期聯編(early binding),即SQL語句在程序編譯期間就已經確定,大多數的編譯情況屬於這種類型;  另外一種

MySQL-靜態SQL 動態SQL

所謂SQL的動態和靜態,是指SQL語句在何時被編譯和執行,二者都是用在SQL嵌入式程式設計中的。 靜態 SQL:靜態 SQL 語句一般用於嵌入式 SQL 應用中,在程式執行前,SQL 語句必須是確定的,例如 SQL 語句中涉及的列名和表名必須是存在的。靜態 S

DB2靜態SQL動態SQL 的比較與實踐

SQL 語言作為標準的查詢語言,幾乎被所有的資料庫管理系統 (DBMS) 所支援,併成為國際標準。標準的 SQL 語言一般包括三類,即 DDL (Data Definition Language, 資料描述語言 ) 、DML (Data Manipulation Language, 資料操縱語言 ) 和 D

ORACLE1.26 綜合:遊標動態SQL

exec _id otf dia 1.2 car num str ber -- 假設分了4個部門(存款部,ATM部,轉出,轉入) --每個月定期最後1天自動生成4張表的數據 --(數據來源:deal_record) -- 第一步:先把4張表建立起來 -- 存款表 creat

Spring boot 配置 mybatis xml動態SQL

star too conn -- 動態 div nec output out 1.pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="

MyBatis的關聯對映動態SQL

一、MyBatis的關聯對映 在實際開發中,實體與實體之間不是孤立存在的,往往實體與實體之間是存在關聯的;例如班級中可以多個學生,每個學生屬於一個班級,這種例項之間相互訪問就是關聯關係。關聯關係分為三類:一對一,一對多,多對多。 1.一對一 比如說,一個人只能有一個身份證,一個身份證只能

靜態靜態動態區別

目前開發的網站其實真正意義上都是動態網站,只是URL上有些區別,一般URL分為靜態URL、動態URL、他們的區別是是什麼? 靜態URL 靜態URL類似 域名/news/2012-5-18/110.html,我們一般稱為靜態URL,每個網頁有真實的物理路徑,也就是真實存在伺服器裡的。

sql union union all 區別使用

1.相同點:  1).union: 用於對多個select查詢結果進行聯合。 2).union all:用於對多個select查詢結果進行聯合。 3).union 和 union all 對select語句的要求:    (1).各個select查詢語句中,各個sel

Java的靜態載入動態載入區別

一、首先是說java的靜態載入: 1.建立了幾個類,“老師”、“學生”、“職員”,每個人群有個屬性方法,程式碼如下: public class Student { public void belongNature() { Syst

Mybatis學習----模糊查詢動態sql

表結構: user:id   name   age 需求:查詢名字中帶有o的和年齡在10,20歲之間的人 重新寫一個模糊查詢的類 FuzzySearch用來封裝查詢條件 FuzzySearch.java package cn.limbo.pojo; /** * Cre

Mybatis中輸入輸出映射動態Sql

list stat map 單表 .get 行動 ets 一個 from 一、輸入映射   我們通過配置parameterType的值來指定輸入參數的類型,這些類型可以是簡單數據類型、POJO、HashMap等數據類型   1、簡單類型   2、POJO包裝類型   ①這

Mybatis 完成CRUD動態sql使用

首先修改一下測試類,將相同的初始化程式碼提取出來: 插入User 對映檔案中加入: 測試方法和執行結果: 根據id查詢User,返回值為:Map 對映檔案中加入: 測試方法和執行結果: 新增User引數為HashMap 對映檔

第四章 PL/SQL動態查詢語句異常處理 練習題答案

動態執行SQL語句: 1、用PLSQL給emp新增dname列,然後更新這個列的資料; 異常和動態執行SQL部分: declare sql_stmt1 varchar2(200); –動態SQL語句 sql_stmt2 varchar2(200);

廣告行業中靜態創意動態創意區別

靜態創意:在投放時,通過選擇事先上傳到 adx伺服器的創意進行投放,這種形式叫靜態創意投放。 動態創意:在投放時,通過在 response 中的 html_snippet 欄位中填寫 html 程式

靜態sql動態sql區別

靜態 SQL:靜態 SQL 語句一般用於嵌入式 SQL 應用中,在程式執行前,SQL 語句必須是確定的,例如 SQL 語句中涉及的列名和表名必須是存在的。靜態 SQL 語句的編譯是在應用程式執行前進行的,編譯的結果會儲存在資料庫內部。而後程式執行時,資料庫將直接執行編譯好的

靜態編譯動態編譯區別

靜態函式庫 一般副檔名為(.a),這類的函式庫通常副檔名為libxxx.a 。 這類函式庫在編譯的時候會直接整合到程式中,所以利用靜態函式庫編譯成的檔案會比較大,這類函式庫最大的優點就是編譯成功的可執行檔案可以獨立執行,而不再需要向外部要求讀取函式哭的內容;但是從升級難易

遊標動態SQL

遊標類別:靜態遊標(指在編譯的時候,遊標就與一個select語句進行了靜態繫結的遊標,這種遊標只能作用於一個查詢語句)和動態遊標(就是希望我們的查詢語句在執行的時候才跟遊標繫結,為了使用動態遊標,必須宣告遊標變數)。 動態遊標分兩種,分別是強型別和弱型別。強型別的動態遊

MyBatis教程3【對映檔案動態sql

1.logj 在程式的執行的過程中為了便於查詢sql的輸出,需要引入logj新增依賴 <dependency> &l

動態SQL是什麽??什麽是靜態SQL動態SQL動態體現在哪裏???

等於 我們 dad var print 動態生成 sca user pan 首先,所謂SQL的動態和靜態,是指SQL語句在何時被編譯和執行,二者都是用在SQL嵌入式編程中的,這裏所說的嵌入式是指將SQL語句嵌入在高級語言中,而不是針對於單片機的那種嵌入式編程。在某種高級語