SQL 命令典型執行程序(以Select為例)
|
Client |
|
|
|
Server |
|
1 |
------- |
Data Piggyback(11) Cursor Close All(69) 注意此處也有可能是 116b,035e,0303 |
-----> |
具體陳述句 |
|
2 |
<----- |
Data DescribeInfo(10) 17 |
------- |
回傳列 |
|
3 |
------- |
Data UOCIFun(03) FetchARow(05) |
-----> |
獲取其他值 |
|
4 |
<----- |
Data RowTransferHeader(06) 01 |
------- |
回傳值 |
11g,12c有三種sql命令執行的模式:
- 第一種是前序一個piggyback(1169)包,然后緊接execute buddle command(035e)
- 第二種是前序一個session switch piggy back(116b)包,然后緊接execute buddle command(035e)
- 第三種是直接發送execute buddle command(035e),前者可以看做只是在后者前面加了一個頭
參考網上其他文章Oracle 9.2還有可能使用0303來發命令,而對其的回傳(上述流程中2處)可能使用data 1019的包
使用0x1169執行SQL命令的情況
包格式
|
|
32bit |
64bit |
|
|
序列號 |
1 |
1 |
|
|
Piggyback cusor close all (1169) command |
9 or 13 |
16 or 20 |
|
|
Buddle execute (035e)command |
變長 |
變長 |
|
參考網上一些文章,Oracle9,10 Piggy Command長度為12
1169 command
這個部分是變長的,下面是幾種變化,都以feMagic(定義參見本系列第二篇 《Oracle TNS 314 協議分析---基礎包結構》)陣列開頭,有的長16個位元組,有的20個位元組
|
陳述句 |
Plsql |
Sqlplus |
Navicat |
|
Select |
fe ff ff ff ff ff ff ff 01 00 00 00 04 00 00 00 |
fe ff ff ff ff ff ff ff 01 00 00 00 00 00 00 00 05 00 00 00 當沒有輸入;05會變03 |
fe ff ff ff ff ff ff ff 01 00 00 00 05 00 00 00 |
|
Update |
fe ff ff ff ff ff ff ff 01 00 00 00 02 00 00 00 |
fe ff ff ff ff ff ff ff 01 00 00 00 00 00 00 00 06 00 00 00 |
|
|
Delete |
fe ff ff ff ff ff ff ff 01 00 00 00 02 00 00 00 |
fe ff ff ff ff ff ff ff 01 00 00 00 00 00 00 00 03 00 00 00 |
|
|
Insert |
|
fe ff ff ff ff ff ff ff 01 00 00 00 00 00 00 00 05 00 00 00 有時是0b 有時是09 |
|
|
CreateTable |
|
fe ff ff ff ff ff ff ff 01 00 00 00 00 00 00 00 07 00 00 00 |
|
使用0x116b執行SQL命令的情況
包格式
|
|
32bit |
64bit |
|
|
序列號 |
1 |
1 |
|
|
Piggy command |
12 |
12 |
|
|
Buddle execute command 035e |
變長 |
變長 |
|
Oracle9 10 Piggy Command長度也為12
Buddle execute Command 035e
|
|
32bit |
64bit |
ThinClient |
|
|
序列號 |
1 |
1 |
1 |
|
|
命令相關 |
8 |
8 |
5 |
|
|
feMagic |
1 |
8 |
1 |
|
|
陳述句長度相關欄位 |
2 |
2 |
1 |
|
| 未知 | 2 | 2 | 1 | |
|
固定位元組 |
54 |
152 |
41 |
所有命令都相同 |
|
SQL命令 |
變長 |
變長 |
變長 |
|
|
尾部位元組 |
52 |
52 |
17 |
01開頭 |
根據其他文章來看Oracle9、10(TNS312,313)下這個包有一定區別(主要是從序列號到SQL的位元組數分別為80,92,而11,12為172)下面是根據其他文章分析的包結構
|
序列號 |
1 |
|
|
固定長度頭部 |
80 or 92 |
|
|
SQL命令 |
變長 |
SQL查詢陳述句 |
|
尾部位元組 |
48 |
|
ThinClient發出的包與此相差較大,將另文描述
命令相關
各個平臺各種陳述句呼叫如下
|
陳述句 |
PlSQL |
SQLplus |
Navicat |
Thin Client |
|
Select |
61 80 00 00 00 00 00 00 |
61 80 00 00 00 00 00 00 |
61 81 00 00 00 00 00 00 |
02 80 21 00 01 |
|
Update |
21 80 00 00 00 00 00 00 |
21 80 00 00 00 00 00 00 |
21 81 00 00 00 00 00 00 |
|
|
Delete |
21 80 00 00 00 00 00 00 |
21 80 00 00 00 00 00 00 |
21 81 00 00 00 00 00 00 |
|
|
Insert |
21 80 00 00 00 00 00 00 |
21 80 00 00 00 00 00 00 |
21 81 00 00 00 00 00 00 |
|
|
CreateTable |
21 80 00 00 00 00 00 00 |
21 80 00 00 00 00 00 00 |
21 81 00 00 00 00 00 00 |
|
|
AlterTable |
21 80 00 00 00 00 00 00 |
21 80 00 00 00 00 00 00 |
21 81 00 00 00 00 00 00 |
紅色部分見過這些取值
61 80 plsql select
61 81 navicat select
01 80 02 plsql select another
29 04 04 plsql declare function
29 05 04 navicat declare function
21 80 plsql 除select 外
21 81 navicat 除select 外
21 01 04 navicat call function
而在ThinClient中,返現Endian會發生變化,且前序一個長度位元組的情況,且此欄位長度也不相同
于是21 80會變成 02 80 21
陳述句長度欄位
此位元組與sql長度有關,OCI Client 下為sql長度欄位大小*3,如果sql較長,則會產生進位,注意進位后是little endian的形式,02 01 表示102,ThinClient下直接就是陳述句長度,ThinClient下陳述句前不會再附加長度,此處是獲取長度的最佳地點,
39 00 00 00 表示 0x39
21 01 00 00 表示 0x121
在命令超長的情況下,這個長度欄位非常有用,因為一個command會在多個TNSData包中出現,必須用這個長度欄位和TNS Command Header的長度欄位,才能正確組合超長命令,

?
上圖中可以看出,一個超長命令可能跨越多個TNS包,如果一個TNS包中的Command長度不足,說明還沒有收取完畢,需要繼續從buffer中讀取資料,直到命令長度滿足要求,另外處理程式如果作業在應用層,那么處理程式從buffer中取出的資料可能橫跨多個TNS包,由于每個TNS包都有自己的頭部,就會在決議的命令中引入這些額外的頭部,為了跳過這些頭部,必須利用第一個TNS 的package Length作為指標,逐個找到每個頭部,從而處理這些額外的10位元組頭,
固定位元組
64bit OCI Client(SQLPLUS,PLSQL,Navicat)
后續19*8=152個固定位元組,使用navicat和plsql無論什么命令都相同:
0000 fe ff ff ff ff ff ff ff 0d 00 00 00 fe ff ff ff ........ ........
0010 ff ff ff ff fe ff ff ff ff ff ff ff 00 00 00 00 ........ ........
0020 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
0030 00 00 00 00 00 00 00 00 00 00 00 00 fe ff ff ff ........ ........
0040 ff ff ff ff 00 00 00 00 00 00 00 00 fe ff ff ff ........ ........
0050 ff ff ff ff fe ff ff ff ff ff ff ff fe ff ff ff ........ ........
0060 ff ff ff ff 00 00 00 00 00 00 00 00 fe ff ff ff ........ ........
0070 ff ff ff ff fe ff ff ff ff ff ff ff 00 00 00 00 ........ ........
0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
0090 00 00 00 00 00 00 00 00 ........
32bit OCI Client(SQLPLUS,PLSQL,Navicat)
后續54個固定位元組
0000 01 0d 00 00 00 01 01 00 00 00 00 01 00 00 00 00 ........ ........
0010 00 00 00 00 00 00 00 00 00 01 00 01 01 01 00 00 ........ ........
0020 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 ........ ........
0030 00 00 00 00 00 00
Thin Client(JAVA)
后續41個固定位元組
0000 01 0d 00 00 04 ff ff ff ff 01 0a 04 7f ff ff ff ........ ........
0010 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ........ ........
0020 00 00 00 00 00 00 00 00 00
Sql命令
后續立刻接sql,sql遵循變長字串或陣列形式,即len+值定義,第一個位元組為長度,或fe表示陣列,陣列中元素也是變長字串,當為陣列時陣列由00結尾,所有sql都后續01,如果輸入時忘記輸入;陳述句后會多個0a,所以結尾看起來是0a01或0a0001(變長),
定長命令
00A0 13 53 45 ........ ......SE
00B0 4c 45 43 54 20 2a 20 46 52 4f 4d 20 44 45 50 54 LECT * F ROM DEPT
00C0 0a 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
00D0 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 ........ ........
00E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
00F0 00 00 00 00 00
變長命令

?
ThinClient 無長度前序命令
ThinClient下發現此包無前序長度,長度由前面長度相關欄位確定
???????包示例(Navicat 15 premium 64bit to Oracle 12)

?
??????? 0303 QUERY包
根據其他文章在Oracle9.2下有可能使用這種包發送命令(本文11,12 64bit下未測得),其格式如下
|
Request id |
1 |
|
|
Magic |
12 |
|
|
Data Format |
可變 |
查詢陳述句 |
??????通過?Transfer header 獲取回傳值
包示例

?
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/2485.html
標籤:Oracle
