A. java程序操作sql報錯 錯誤為: 並非所有變數都已綁定
您好,建議把sql語句在資料庫中執行下,看能否正確執行。
我想大概是表裡面所有的欄位,你沒有給全部賦值。
因為你insert into t_login 後面沒有具體欄位,那麼就是全表的所有欄位。
values後面給了三個欄位。
B. 什麼是SQL綁定變數,如何實現綁定變數
1. 認識綁定變數:
綁定變數是為了減少解析的,比如你有個語句這樣
select aaa,bbb from ccc where ddd=eee;
如果經常通過改變eee這個謂詞賦值來查詢,像如下
select aaa,bbb from ccc where ddd=fff;
select aaa,bbb from ccc where ddd=ggg;
select aaa,bbb from ccc where ddd=hhh;
每條語句都要被資料庫解析一次,這樣比較浪費資源,如果把eee換成「:1」這樣的綁定變數形式,無論ddd後面是什麼值,都不需要重復解析
Java實現綁定變數的方法:
[java] view plain
PreparedStatement pstmt = con.prepareStatement("UPDATE employees SET salay = ? WHERE id = ?");
pstmt.setBigDecimal(1, 15.00);
pstmt.setInt(2, 110592);
/result statmement: UPDATE employees SET salay = 15.00 WHERE id = 110592
pstmt.executeQuery();
假設要將id從1到10000的員工的工資都更新為150.00元,不使用綁定變數,則:
[java] view plain
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 1");
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 2");
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 3");
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 4");
....
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 10000");
使用綁定變數,則:
[java] view plain
PreparedStatement pstmt;
for (id = 1; id < 10000; id )
{
if (null == pstmt)
pstmt = con.prepareStatement("UPDATE employees SET salay = ? WHERE id = ?");
pstmt.setBigDecimal(1, 150.00);
pstmt.setInt(2, id);
pstmt.executeQuery();
}
二者區別在於,不用綁定變數,則相當於反復解析、執行了1w個sql語句。使用綁定變數,解析sql語句只用了一次,之後的9999次復用第一次生成的執行計劃。顯然,後者效率會更高一些。
2. 什麼時候不應該/不必要使用綁定變數
a. 如果你用數據倉庫,一條大查詢一跑幾個小時,根本沒必要做綁定變數,因為解析的消耗微乎其微。
b. 變數對優化器產生執行計劃有很重要的影響的時候:綁定變數被使用時,查詢優化器會忽略其具體值,因此其預估的准確性遠不如使用字面量值真實,尤其是在表存在數據傾斜(表上的數據非均勻分布)的列上會提供錯誤的執行計劃。從而使得非高效的執行計劃被使用。
3. 綁定變數在OceanBase中的實現
目前OceanBase中實現了綁定變數,目的主要是為了編程方便,而不是為了降低生成執行計劃的代價。為什麼呢?因為OceanBase中目前使用的是一種」靜態執行計劃「,無論什麼Query,執行流程都一樣。OB在前端代理ObConnector中實現綁定變數,將用戶傳入的變數進行to_string()操作,替代SQL語句中相應的部分,形成一個完整的SQL。然後這個SQL傳遞給MS,MS按照標准流程來解析和執行。相信不遠的將來,OB將會實現真正意義上的綁定變數,讓用戶享受到綁定變數帶來的好處。
C. java.sql.SQLException: ORA-01006: 綁定變數不存在
你system("SELECT name FROM Test WHERE FID="+paras[2]+" FOR UPDATE")這個出來,看下你拼接的,跟你測試的,是不是一摸一樣。然後把system出來的這句,復制過去,看能執行不,肯定有拼接錯誤的,仔細看下
D. 拼的sql,怎麼使用綁定變數
很多方法 1.自定義函數返回集合,然後用table,注意計劃,可能要用rownum固定 2.正則表達式 3.INSTR+SUBSTR 4.SYS_CONTEXT 反正不管哪種方法,計劃符合條件,可用到綁定變數,那麼就可以了
E. 求已SQL語句報錯的問題,報什麼並非所有的變數都已綁定,代碼在補充中:
報的錯誤是not all variables bound(並非所有的變數都已綁定)對吧?語句錯誤的來源是
'BEGIN SELECT count(carinfoid) INTO :1 FROM test ; END
這句話是作為一個語句來單獨執行的,是脫離你這個過程,自己去執行的,把他單拿出來執行就會報這個錯誤。
如果你不動態執行它,應該就沒問題了。而且INTO :1是什麼?
F. 怎樣察看沒有使用綁定變數的sql語句
FORCE_MATCHING_SIGNATURE的值相同,而EXACT_MATCHING_SIGNATURE值不同,說明在cursor_sharing=force時,執行計劃可共用;
cursor_sharing=exact時,執行計劃不可共用;
實際上我們使用綁定變數後,同樣也可以達到執行計劃共用的效果。
G. 如何找出未使用綁定變數的SQL
可以看到insert into test.......這條語句竟然在shared pool裡面解析了1000次,通過如下查詢
select sql_text from v$sqlarea where sql_text like 'insert into test %';找出具體的sql代碼,然後與開發人員商量,更改SQL代碼。
上面只是一個簡單的實例,具體要怎麼查看你的應用是否使用了綁定變數,只需要簡單修改
select substr(sql_text,1,20), count(*)
from v$sqlarea
group by substr(sql_text,1,20) having count(*) > 50;
可以將substr(sql_text,1,20) 改為substr(sql_text,1,30)等等,可以 having count(*) > 10,20,100等等。