什麼是sql預編譯
A. 靜態的sql 和動態的SQL有什麼區別
靜態 SQL:靜態 SQL 語句一般用於嵌入式 SQL 應用中,在程序運行前,SQL 語句必須是確定的,例如 SQL 語句中涉及的列名和表名必須是存在的。靜態 SQL 語句的編譯是在應用程序運行前進行的,編譯的結果會存儲在資料庫內部。而後程序運行時,資料庫將直接執行編譯好的 SQL 語句,降低運行時的開銷。
動態 SQL:動態 SQL 語句是在應用程序運行時被編譯和執行的,例如,使用 DB2 的互動式工具 CLP 訪問資料庫時,用戶輸入的 SQL 語句是不確定的,因此 SQL 語句只能被動態地編譯。動態 SQL 的應用較多,常見的 CLI 和 JDBC 應用程序都使用動態 SQL。
B. SQL注入預編譯是絕對安全的么
沒錯,存儲過程的確能有效解決SQL注入式攻擊!
理由:因為通常的資料庫訪問方法,都是把訪問數據表的權利賦給程序,注入式攻擊者通過你的程序漏洞判斷和獲得更多的信息,並利用你賦給程序的訪問和操作權,輕者破壞本表數據,重者毀壞整個資料庫!
使用存儲過程則完全不同,程序中不必再有SQL語句,因此程序不必擁有訪問和操作數據表的許可權,只把運行存儲過程的許可權交給程序。程序只是把參數和存儲過程名告訴資料庫,然後等待結果就行了,注入式攻擊者要想運行存儲過程,就必需猜對存儲過程名,並且還要猜對參數個數、參數名和參數的順序,同時滿足這些條件太難了,即便所以條件都滿足,那麼攻擊者也只是往數據表裡存了一組合法數據而已,不會導致其它破壞。
因此,通過存儲過程能從根本上解決注入式攻擊。
需要注意的是,使用存儲過程後,應把原來交給程序的操作數據表的許可權收回,否則就象為了防小偷鎖了前門,卻開著後門一樣。
C. 預編譯sql語句就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將會實現真正意義上的綁定變數,讓用戶享受到綁定變數帶來的好處。
D. SQL語句問題:存儲過程定義是什麼什麼時候用它作用是什麼怎樣寫,來個實例!
定義:存儲過程是一組為了完成特定功能的SQL語句集,是利用SQL Server所提供的Transact-SQL語言所編寫的程序。作用:將常用或復雜的工作,預先用SQL語句寫好並用一個指定名稱存儲起來, 以後需要資料庫提供與已定義好的存儲過程的功能相同的服務時,只需調用execute,即可自動完成命令。什麼時候用:提高資料庫執行速度,對資料庫進行復雜操作,重復使用,安全要求高例子: CREATE PROCEDURE order_tot_amt @o_id int, @p_tot int output AS SELECT @p_tot = sum(Unitprice*Quantity) FROM orderdetails WHERE ordered=@o_id GO
E. C語言:預編譯是什麼
預編譯,顧名思義,從字面上看,就是提前編譯,它做的是工作就是為正式編譯做准備
它說處理的是有#標識的代碼,如講include的文件進行拷貝、#define的條件編譯等等!關於預編譯的介紹你可以到網路里進行查看,裡面有詳細的介紹!http://ke..com/view/176610.htm
F. pstmt = conn.prepareStatement(sql);是什麼意思
pstmt = conn.prepareStatement(sql)是執行SQL語句的一個介面。但是執行前會對SQL語句進行預編譯的操作,然後就開始執行SQL語句,並把結果賦值給pstmt。conn的意思是一個資料庫連接。
PreparedStatement是Statement的子介面,表示預編譯的 SQL 語句的對象,SQL 語句被預編譯並存儲在PreparedStatement對象中。然後可以使用此對象多次高效地執行該語句。如果有參數的話還需要添加輸入的參數。
(6)什麼是sql預編譯擴展閱讀:
資料庫建立連接的五大步驟:
1、載入(注冊)資料庫
裝載驅動程序只需要非常簡單的一行代碼。例如,你想要使用 JDBC-ODBC 橋驅動程序,可以用下列代碼裝載它:Class.forName("sun.jdbc.odbc.JdbcOdbcDriver")。
你的驅動程序文檔將告訴你應該使用的類名。例如, 如果類名是 jdbc.DriverXYZ ,你將用代碼以下的代碼裝載驅動程序:Class.forName("jdbc.DriverXYZ")。
你不需要創建一個驅動程序類的實例並且用 DriverManager 登記它,因為調用 Class.forName 將自動將載入驅動程序類。載入 Driver 類後,它們即可用來與資料庫建立連接。
2 、建立鏈接
第二步就是用適當的驅動程序類與 DBMS 建立一個連接。下列代碼是一般的做法:
Connection con = DriverManager.getConnection(url,"myLogin","myPassword")
3 、執行SQL語句
我們使用 executeUpdate 方法是因為在 createTableCoffees 中的 SQL 語句是 DDL (數據定義語言)語句。創建表,改變表,刪除表都是 DDL 語句的例子,要用 executeUpdate 方法來執行。
4、 處理結果集
5 、關閉資料庫
參考資料來源:網路-Java資料庫連接
G. sql預編譯語句就是不執行,怪怪的,求解,急~~
你上面的語句是傳參數查詢嗎?應該是參數沒有傳進去,下面的語句語法沒有錯誤,但是可以返回的查詢結果不是正確的.建議寫成封裝的,不易SQL注入.
比如:
public DataTable SelectAId(pb_list_of_value prep )
{
sql = "SELECT tstand_code from pb_list_of_value where display_value=@display_value and type =@type order by display_value desc ";
sqlpar = new List<SqlParameter>();
sqlpar.Add(newSqlParameter("@display_value",pb_list_of_value.display_value));
DataTable ds=DBHepler.SQLDBHepler.Search(sql,sqlpar,CommandType.Text);
return ds;
}
加粗部分不換行
H. SQL注入的防範 使用預編譯語句
預編譯語句PreparedStatement是 java.sql中的一個介面,繼承自Statement 介面。通過Statement對象執行SQL語句時,需要將SQL語句發送給DBMS,由 DBMS先進行編譯後再執行。而預編譯語句和Statement不同,在創建PreparedStatement對象時就指定了SQL語句,該語句立即發送給DBMS進行編譯,當該編譯語句需要被執行時,DBMS直接運行編譯後的SQL語句,而不需要像其他SQL語句那樣先將其編譯。引發SQL注入的根本原因是惡意用戶將SQL指令偽裝成參數傳遞到後端資料庫執行。作為一種更為安全的動態字元串的構建方法,預編譯語句使用參數佔位符來替代需要動態傳入的參數,這樣攻擊者無法改變SQL語句的結構,SQL語句的語義不會發生改變,即便用戶傳入類似於前面' or '1'='1這樣的字元串,資料庫也會將其作為普通的字元串來處理。
I. sql是解釋型語言還是編譯型語言
結構化查詢語言(Structured Query Language)簡稱SQL,是一種特殊目的的編程語言,是一種資料庫查詢和程序設計語言,用於存取數據以及查詢、更新和管理關系資料庫系統。
結構化查詢語言是高級的非過程化編程語言,允許用戶在高層數據結構上工作。它不要求用戶指定對數據的存放方法,也不需要用戶了解具體的數據存放方式,所以具有完全不同底層結構的不同資料庫系統, 可以使用相同的結構化查詢語言作為數據輸入與管理的介面。結構化查詢語言語句可以嵌套,這使它具有極大的靈活性和強大的功能。
SQL從功能上可以分為3部分:數據定義、數據操縱和數據控制。
SQL的核心部分相當於關系代數,但又具有關系代數所沒有的許多特點,如聚集、資料庫更新等。它是一個綜合的、通用的、功能極強的關系資料庫語言。其特點是:
1、數據描述、操縱、控制等功能一體化。
2、兩種使用方式,統一的語法結構。SQL有兩種使用方式。一是聯機交互使用,這種方式下的SQL實際上是作為自含型語言使用的。另一種方式是嵌入到某種高級程序設計語言(如C語言等)中去使用。前一種方式適合於非計算機專業人員使用,後一種方式適合於專業計算機人員使用。盡管使用方式不向,但所用語言的語法結構基本上是一致的。
3、高度非過程化。SQL是一種第四代語言(4GL),用戶只需要提出「干什麼」,無須具體指明「怎麼干」,像存取路徑選擇和具體處理操作等均由系統自動完成。
4、語言簡潔,易學易用。盡管SQL的功能很強,但語言十分簡潔,核心功能只用了9個動詞。SQL的語法接近英語口語,所以,用戶很容易學習和使用。
J. ps.executeUpdate(); 是什麼意思
是當成功插入數據到資料庫時候,這個會返回一個大於1的數字,來表明數據成功插入庫之中
sql注入發生的時間,sql注入發生的階段在sql預編譯階段,當編譯完成的sql不會產生sql注入,採用jdbc操作數據時候,preparedStatement 預編譯對象會對傳入sql進行預編譯。
那麼當傳入id 字元串為 "update ft_proposal set id = 3;drop table ft_proposal;" 這種情況下就會導致sql注入刪除ft_proposal這張表。
預編譯語句
處理使用預編譯語句之外,另一種實現方式可以採用存儲過程,存儲過程其實也是預編譯的,存儲過程是sql語句的集合,將所有預編譯的sql語句編譯完成後,存儲在資料庫上。
當傳入的參數為3;drop table user;當執行時可以看見列印的sql語句為:select name from usre where id = ?;不管輸入何種參數時,都可以防止sql注入,因為mybatis底層實現了預編譯。