oraclesqlin參數化
Ⅰ 如何調整oracle中的sql語句輸入的最大長度
Oracle SQL 語句in長度不得超過1000
IN 子句中的LIST個數最長為1000,超過該數目將報錯,這里可轉用一個臨時表來解決;CREATE TRIGGER語句文本的字元長度不能超過32KB(觸發器中不能使用LONG, LONG RAW 類型;觸發器內可以參照LOB 類型列的列值,但不能通過 :NEW 修改LOB列中的數據;)順便說一下,觸發器中的PARENT關鍵字,只在嵌套表觸發器中有效,11G以前,DBMS_SQL對輸入的SQL長度不能超過32K,原因是輸入參數只能是VARCHAR2類型,11G後,可以用CLOB作為輸入參數,則取消了這個限制一個PL/SQL的包、過程、函數、觸發器的大小,在UNIX上最大是64K,而WINDOWS則是32K大小(32K這個應該不準,看下面的測試)SQL語句可以有多長?(網友說)ORACLE文檔說是64K,實際受一些工具的限制會較這個值低,但網友測試發現可以很長,甚至超過1M(我測試過 170K的都沒問題)。具體多長,10G也未說明,只是與很多環境有關:資料庫配置,磁碟空間,內存多少。。。
PL/SQL中,表達式/SQL本身的長度是可以達到比較長的長度(50K)左右,如:v_str:=:new.f1||:ndw.f2。。。 ; select :new.f1||:new.f2。。。 into v_str from al; 另外發現,如果這樣寫:v_str := 『a』||』b』||。。。則允許的表達式長度將大大的減少。如果表達式/SQL過長,超過了一個ORACLE包/過程允許的最大程序長度,則在編譯時報 pls-123:program too large錯誤,這是pl/sql編譯器本身的限製造成的,即表達式/SQL的長度在PL/SQL中受限於包/過程的最大大小=================================================Oracle Sql語句長度限制問題及解決
最近在寫Sql語句時,碰到兩個問題:
1)ORA-01795: maximum number of expressions in a list is 1000起因:寫出了這樣的sql語句:SELECT PALLET_ID,BOX_ID,STATUS FROM SD_CURRENT_BOX WHERE PALLET_ID IN('"+pallets+"');其中的pallets是有很多個pallet_id組合成的字元串。
分析:很顯然,根據錯誤提示可以知道:in 中items的限制 1000個。
解決:用子查詢來代替pallets長字串。
2)ORA-01704: string literal too long
起因:寫出了這樣的Sql語句:UPDATE PDM_MEMBERLIST SET MEMBERS='<Project> ... 此處略去n多串 <ProjectID>'.
分析:資料庫設計MEMBERS欄位為xmltype格式,數據存儲時候,是以字元串的形式存儲。這樣在xml數據量大的時候,造成sql語句過長,嘗過2k的限制。
解決:參數化sql語句。
==================================================參數化sql語句----防止sql注入攻擊(下)
上一篇寫的sql注入的基本原理,本來要接著寫這篇的,但是由於時間的原因一直沒有寫成,今天是五一假期,總算是能抽空寫寫了。
作為一個程序員,防範sql注入的第一線是由我們來守護的,只要我們在程序中留少許的漏洞,就會給程序增強安全特性。所以我們要做的是要寫安全的程序,防止sql注入在程序體現在不要拼接sql字元串,一定要參數化sql或者寫存儲過程,這里就說說簡單的參數化sql吧。
例子中用c#和Oracle實現,Java中或者其他資料庫中的實現也是類似的。
using System.Data.OracleClient;//引入oracle操作包//定義DML語句
string strSQL = @"select user.name from user where user.name =:userName";//上句中的:userName就是sql語句中參數的佔位符,也就是說在資料庫伺服器中執行這條sql語句的時候這個佔位符要被其他東西替換掉,到底用什麼東西替換呢,接著往下看OracleParameter[] param = {
new OracleParameter(":userName",txtName);}//這里定義一個參數的數組,裡面可以寫入多個sql參數,咱們的這里只有一個,所以就寫入一個參數,這里講佔位符和他的替換也就是參數值對應起來了,txtName就是佔位符的替換值,他是用戶界面中用戶輸入的值,就是他可能含有注入攻擊的字元,這下資料庫伺服器知道用什麼東西替換佔位符了。
定義好sql語句和參數後就是執行了,執行的時候需要同時將sql語句和參數傳入,這樣用戶輸入的帶有非法字元的字元串在資料庫會當作參數處理,而不會當作sql語句和資料庫自己的字元混亂,防止了注入攻擊。
OracleCommandcmd = new OracleCommand();
cmd.CommandText= strSQL;//定義oracle命令的文本內容for(oracleParameter p in param)//將參數傳入{
cmd.Parameters.Add(p);
}
cmd.ExecuteNonQuery();//執行命令
上面基本上是一個完整的參數化sql,不同的資料庫伺服器sql語句中參數的佔位符不同,上面用的是oracle,參數佔位符是冒號(:)加名字,在sqlserver中是用@符號加名字作為佔位符,而在MySQL中用問號(?)加名字來作為參數佔位符,不同的資料庫中參數的表示符號不一樣,這個需要注意。
防止sql注入攻擊(上)
Sql注入是一種入門極低破壞極大的攻擊方式。如果sql是用字元串拼接出來的話,那麼肯定會被注入攻擊,前段時間還傳出了某國外大型社交網站被SQL注入攻擊。
Sql注入攻擊的方式,來這里看的同志們應該很清楚了,就是在拼接字元串的時候,如果輸入的是帶單引號的,那麼輸入laf'or 1='1'--這樣就會逃避條件檢查,後面要是再跟一些shutdown,delete之類的條件,那麼損失基本算是毀滅性的了。前幾天單位開發的過程中我發現幾乎大家都不重視安全,一個寫代碼的人不注意安全只注意實現那麼寫出來的代碼在攻擊者眼前基本就是一個沒有穿衣服的美女。
下面是我一個開發人員的一些經驗,主要用來防止sql注入。
1、首先對運行sql的用戶賦予最小許可權,這個理論也是安全領域的最小特權理論,運行一個程序一定要用最小特權運行,所以不要給用戶服務DBA的許可權,限制要許可權之後可以防止一些毀滅性的攻擊,即使攻入了也不會shutdown修改表之類的。
2、一定不要使用字元串拼接的方式構造sql,必須使用參數化sql,存儲過程可以看作是參數sql,簡單的就直接構造參數化sql,復雜的就寫存儲過程,不過存儲過程中一定不要用字元串,我看有人在存儲過程用字元串,這樣還是不能避免被攻擊,並且在調試的時候非常麻煩。
3、嚴把輸入關,系統肯定是用來交互的,所有用戶輸入的這一關一定要把好,可以利用各種方式來檢驗用戶的輸入,讓輸入都是合法的;可以設敏感字元不讓用戶輸入,這個雖然不是很友好,不過對與安全有保證。在驗證的是可以用正則表達式或者程序驗證,不管用什麼方式只要把敏感字元和可疑字元拒之門外那麼就無法攻擊了,不過限制輸入還是有缺陷,在安全理論方面,只能確定合法,不能確定不合法,比如你在界面限制了合法的,那麼剩餘的都是不合法的,這時候輸入的肯定全部是合法的,如果你限制的是非法的,可是你能確保你限制的全是非法的?如果某一天發現一個非法的不再你限制之內那麼你就會被攻擊。
4、做好自己的檢驗和測試工作,自己可以進行sql注入攻擊,利用工具檢驗。
5、一定要養成具有安全意識的程序員,時刻想著安全。
這幾條之中最重要的是1和2,許可權限制一定要注意,不然會死的很慘的,第二就是程序員的習慣了,一定要用參數化sql和資料庫交互。