運用設計模式實現Sql語句動態轉換

2021-03-31 08:56:59 字數 2725 閱讀 2487

由於系統面向

客戶的實際情況不同,對資料庫的選擇上,有的偏向於

sql server

的易用性和可維護性,有的偏向於

oracle

的健壯性和穩定性,而現有**中

sql語句都大量應用伺服器端的函式和關聯(oracle),這些函式呼叫的名稱、引數等在這不同資料庫中有很大的差別。如果為每種資料庫去維護乙份**,將來的維護成本將會越來越高;如果要有功能的公升級,對**的修改量將是幾何級數的增加。

對於這個問題,開始的設想比較簡單,在執行

sql語句前,首先檢查當前所連線的資料庫,如果是

oracle

則不作任何干涉,如果是連線

sqlserver

只要把sql

語句中不相同的關鍵字和函式名替換掉,如

oracle

中的to_date

換成sqlserver

的convert

,就可以在

sqlserver

上執行了,對一些簡單的

sql語句這樣確實可以,可是對系統中大量複雜報表的應用來說,

sql語句可能多層巢狀,函式也有多層巢狀,如果只是簡單的替換,將會有無數的

if else

,並且出錯後的修改和除錯幾乎是不可能的。

通過對oracle

和sqlserver

兩種資料庫的

sql語法的研究比較,認為必須採用語法分析,把

sql語句解析為一棵語法樹,然後再按照語法的轉換規則把

sql語句轉換到

sqlserver

上可執行的語句。要實現這樣的功能,需要用到的模式有:

1.interpreter(

直譯器)

—類行為型模式:給定乙個語言,定義它的文法的一種表示,並定義乙個直譯器,這個直譯器使用該表示來解釋語言中的句子。通過實現直譯器模式,把要執行的

sql語句解釋為

sql的語法樹。例如乙個

select

語句的結構如下

從這張結構圖中可以看到,

sql語句可能出現非常複雜的組合結構,如果不使用語法樹表示,很難實現不同資料庫平台的轉換。

在系統中,呼叫

sql語句轉換功能的是

tadodataset

或tadoquery

,也就是模式中的

client

。所以運用該模式的類關係如下

2.***posite

(組合)—物件結構型模式:將物件組合成樹形結構以表示「部分

-整體」的層次結構。

c o m p o s i t e

使得使用者對單個物件和組合物件的使用具有一致性。

從上面的

sql語句的語法結構可以看到乙個查詢語句可能是很簡單的

select * from atable

,也可能在

sql裡面又包含其他的

sql語句。按照組合優先於繼承的規則,並沒有給單獨的

sql和復合的

sql語句建立不同的類,而是在內部組合並遞迴引用自己的定義,對訪問語法樹的客戶**來說,並不需要了解所訪問的

sql語句是否存在復合結構。

3.visitor

(訪問者)—物件行為型模式:表示乙個作用於某物件結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。

前面已經通過直譯器模式解析

sql語法,用組合模式來儲存解析的語法樹,但是我們所需要的不僅如此。還要按照

sqlserver

的語法結構把語法樹上的各個節點重新組合,最終輸出

sqlserver

上可以執行的

sql語句。例如:

oracle

中的一句連線查詢

select a.*,b.* from a,b where a.id=b.id(+),

在sqlserver

中對應的語句應該是

selecta.*,b.* from a left join b on a.id=b.id

。從這個簡單的例子中可以看到對於表的左連線或右連線,兩種資料庫的語法結構存在較大的差異。如果是在

tsql

類中寫某個方法,由這個方法遍歷語法樹上的每個節點,並按照

sqlserver

的語法結構組合所需要的結果,是可以達到這個目的的。可是如果需要從這棵語法樹匯出其它資料庫上如

sybase

可執行的

sql語句呢,那又要在

tsql

類中再增加新的遍歷演算法,所有的相關**又要重新編譯。通過採用訪問者模式,把遍歷節點時組合語法樹節點的演算法封裝再訪問者的方法中,如

sqlserver

的語法就是乙個

tsqlservervisitor

類,語法樹遍歷每個節點時,都會呼叫它的

visit

方法,全部訪問完後即可通過

getsql

得到所需要的

sql語句。這時如果我們需要轉換到

sybase

,只需要再實現乙個

tsybasevisitor

類,並傳給語法樹,就可以得到

sybase

的sql

語句了.

動態SQL語句的拼接實現

平常經常遇到一些語句需要使用動態語句,來實現作業任務的計畫執行。例如動態表名,在分表設計時使用了月份格式 a 201912 在實現此類格式表名的作業任務時,必須採用動態語句,以避免每月更換一次sql語句的尷尬。現將部分實際操作經驗總結如下 一 基本語句格式 定義變數,給變數賦值,使用變數拼接sql,...

MyBatis的動態SQL語句實現

1.動態sql之標籤 我們根據實體類的不同取值,使用不同的sql語句來進行查詢。比如在id如果不為空時可以根據id查詢,如果username不為空時還要加入使用者名稱作為條件,這種情況在我們的多條件組合查詢中經常會碰到。ggmd ebuhhojjm mapper.dtd select from us...

動態SQL語句

動態使用sql語句的幾點技巧 動態sql語句,就是sql語句中引數會變化的sql語句,一般在程式中要根據使用者的需要隨時改變其引數值,對於動態sql語句必須注意以下幾點 先呼叫close方法,關閉query元件。如果query元件已經關閉,呼叫close方法不會出錯,也沒有其它影響。再呼叫clear...