在長期的停滯后,Open SQL的發展終於從沉睡中醒來。從ABAP 7.40開始,SAP推進了某些關鍵的改變,以盡可能地包含SQL92中的特性,並提供與ABAP CDS中的DDL里面的SELECT一樣的功能給Open SQL。為了實現這些目標,ABAP運行時環境中引入了一個新的SQL parser作為Open SQL的新基礎。結果就是,Open SQL現在可以在ABAP中扮演一些和以往不同的角色了。
雖然在7.40之前,Open SQL更多地被視為ABAP語言本身的一部分,但在同時,SQL關鍵字變得越來越介詞化了。關於這點,主要的體現之一便是有關宿主變量的新規則。在7.40之前,你可以像在其它ABAP語句中使用ABAP變量那樣在Open SQL中使用它們。實際上,這種自由阻止了更高效的開發。Open SQL語句在被轉換為native SQL之后才會在數據庫中運行。為了在WHERE條件中實現比簡單比較更為復雜的東西,Open SQL parser必須能清晰的區分運算符兩端的東西到底是ABAP變量、還是數據庫內容,從而發送相應的內容給數據庫。為了完成這一任務,Open SQL中的ABAP變量因此成為了完全的宿主變量(host variables)。就像ABAP變量在native SQL中的成分一樣(EXEC SQL)。你可以(而且應當)在Open SQL中的ABAP 宿主變量前加上轉義符@。實際上,只有這樣做了,你才能使用ABAP 7.40版本之后的全部Open SQL新特性。Open SQL中引入的其它的基礎修改也是為了讓其更加適應未來,比如逗號分隔、以及將SELECT語句的INTO附加項放在authentic SQL子句的后面。(譯注:authentic是什么意思沒看懂,不過這句話的意思應當是指INTO語句不應是SQL本身的一部分,所以要放到后面以示區分)
這些方法帶來的第一個好處,已經在ABAP 7.40版本中放出,包括可以在不同操作數位置使用的SQL表達式,以及內聯聲明的可能性。在ABAP 7.50中,Open SQL依然在發展着,本文將介紹一些新特性(未來還會有更多)。
本文鏈接:http://www.cnblogs.com/hhelibeb/p/7135899.html
原文標題:ABAP News for Release 7.50 – Host and Other Expressions in Open SQL
宿主表達式
在大多數可以放置宿主變量的地方,包含7.40版本以來的SQL表達式的操作數位置或者寫SQL語句的工作區,現在可以通過如下方式放置宿主表達式(host expression):
… @( abap_expression ) …
宿主表達式abap_expression可以是任何ABAP表達式,可以是一個構造器表達式、表表達式、算術表達式、字符串表達式、bit表達式、內建函數、函數性的方法、或者是方法,它通過括號()包圍起來,並且要加上前綴@。Open SQL中的宿主表達式從左到右計算,並且它們的結果會作為宿主變量傳遞給數據庫。事實上,你可以將宿主表達式視為通過ABAP表達式為ABAP幫助變量賦值的簡寫。以下例子演示了一個表表達式,表達式從內表carriers中讀取值,並放置在where條件右端:
SELECT carrid, connid, cityfrom, cityto FROM spfli WHERE carrid = @( VALUE spfli-carrid( carriers[ KEY name carrname = name ]-carrid OPTIONAL ) ) INTO TABLE @DATA(result)
我個人喜歡下面的語句:
DATA(rnd) = cl_abap_random_int=>create( seed = CONV i( sy-uzeit ) min = 1 max = 100 ). INSERT demo_expressions FROM TABLE @( VALUE #( FOR i = 0 UNTIL i > 9 ( id = i num1 = rnd->get_next( ) num2 = rnd->get_next( ) ) ) ).
這段代碼構造了一個填充了隨機數字的內表,接着在INSERT語句中用到了它。這是ABAP文檔里面的一個很酷的demo程序。
更多信息,請查看宿主表達式
SQL表達式
在ABAP 7.50 中,SQL表達式的使用得到了擴展:
- 除了在SELECT列表中使用它們,你現在可以在WHERE, HAVING, ON和CASE的左手端作為CAST的操作數使用它們。注意,這會把包含的宿主變量和宿主表達式作為SQL表達式的操作數處理。
- 以下SQL函數現可用於SQL表達式:ROUND, CONCAT, LPAD, LENGTH, REPLACE, RIGHT, RTRIM, SUBSTRING。而COALESCE函數的參數上限現在達到了255個。
一個WHERE左手端的算術表達式示例:
SELECT carrid, connid, fldate, seatsmax, seatsocc, seatsmax – seatsocc AS seatsfree FROM sflight WHERE seatsmax – seatsocc > @( meth( ) ) INTO TABLE @DATA(result).
通過字符串函數使用CONCAT將列拼接的例子:
SELECT CONCAT( CONCAT( carrid, LPAD( carrname,21,’ ‘ ) ), LPAD( url,40,’ ‘ ) ) AS line FROM scarr INTO TABLE @DATA(result).
通過運算符&&拼接這樣的字符串是不可以的。(譯注:似乎是指&&只能用來拼接字符型的值)
更多信息請看SQL表達式。
路徑表達式
路徑表達式是一種你已經從CDS中了解過的概念。如果一個CDS視圖暴露出關聯相同的或者不同的視圖可以通過路徑表達式訪問它。
例如,下面的CDS視圖在它的SELECT列表里面用到了路徑表達式:
@AbapCatalog.sqlViewName: ‘DEMO_CDS_USE_ASC’ @AccessControl.authorizationCheck: #NOT_REQUIRED define view demo_cds_use_assocs with parameters p_carrid:s_carrid as select from demo_cds_assoc_scarr as scarr { scarr.carrname, scarr._spfli.connid, scarr._spfli._sflight.fldate, scarr._spfli._sairport.name } where scarr.carrid = :p_carrid
關聯的名字以underscore_為前綴,並且通過如下的視圖定義:
@AbapCatalog.sqlViewName: ‘DEMO_CDS_ASC_CAR’ @AccessControl.authorizationCheck: #NOT_REQUIRED define view demo_cds_assoc_scarr as select from scarr association to demo_cds_assoc_spfli as _spfli on scarr.carrid = _spfli.carrid { _spfli, carrid, carrname } @AbapCatalog.sqlViewName: ‘DEMO_CDS_ASC_SPF’ @AccessControl.authorizationCheck: #NOT_REQUIRED define view demo_cds_assoc_spfli as select from spfli association to sflight as _sflight on spfli.carrid = _sflight.carrid and spfli.connid = _sflight.connid association [1..1] to sairport as _sairport on spfli.airpfrom = _sairport.id { _sflight, _sairport, carrid, connid, airpfrom }
在ABAP 7.50中,訪問CDS視圖時,Open SQL的SELECT語句也可以在它的SELECT清單或者FROM子句中使用這樣的路徑表達式。下面的SQL語句實現了和上面的CDS視圖一樣的功能:
SELECT scarr~carrname, \_spfli-connid AS connid, \_spfli\_sflight-fldate AS fldate, \_spfli\_sairport-name AS name FROM demo_cds_assoc_scarr AS scarr WHERE scarr~carrid = @carrid ORDER BY carrname, connid, fldate INTO TABLE @DATA(result).
看起來區別不算大,是吧?唯一的就是點被反斜杠 \ 代替了(因此,路徑表達式看起來像那些meshes)。當編譯這些Open SQL的時候,路徑表達式將被轉換為數據庫中的join。可以在ST05中觀察這點。
更多信息請查看路徑表達式。
其它新聞
這不是有關ABAP 7.50中的Open SQL的全部信息。下篇文章我將會展示SELECT語句得到的增強,這使得INTO可以放置在SELECT后的末尾...