㈠ 如何使用sql語句實現這個思路
先創建一個自增臨時表
select 自增=identity(int,1,1) into #tb from syscolumns a,syscolumns b
select * from #tb t where not exists(select * from tb where t.自增=id) and t.自增<=(select max(id) from tb)
㈡ sql資料庫質疑的原因及解決辦法
sql資料庫質疑是設置錯誤造成的,解決方法為:
1、通過DBCC CHECKCB('DBName') 來檢測資料庫異常的原因,如果可以檢測到資料庫的異常,其中紅色部分即時數據目前存在的問題,我們也在檢測結果最後看到數據的總體的錯誤情況的匯總。
㈢ sql資料庫後台處理的方法
private const int MaxPool = 10000; //最大連接數
private const int MinPool = 0; //最小連接數
private const bool Asyn_Process = true; //設置非同步訪問資料庫
private const bool Mars = true; //在單個連接上得到和管理多個、僅向前引用和只讀的結果集(ADO.NET2.0)
private const int Conn_Timeout = 15; //設置連接等待時間
private const int Conn_Lifetime = 15; //設置連接的生命周期
//private string ConnString = ""; //連接字元串
// private SqlConnection SqlDrConn = null; //連接對象
private static SqlConnection connection;
public static SqlConnection Connection
{
get
{
//string connectionString = ConfigurationManager.ConnectionStrings["Notoko"].ConnectionString;
//string connectionString = ConfigurationSettings.AppSettings["ConnectionString"];
//string connectionString = "Data Source=.;Initial Catalog=notoko;Integrated Security=True;User ID=sa;Pwd=123";
string connectionString = "Data Source=.;"
+ "integrated security=True;"
+ "database=notoko;"
+ "User ID=sa;"
+ "Pwd=123;"
+ "Max Pool Size=" + MaxPool + ";"
+ "Min Pool Size=" + MinPool + ";"
+ "Connect Timeout=" + Conn_Timeout + ";"
+ "Connection Lifetime=" + Conn_Lifetime + ";"
+"Asynchronous Processing=" + Asyn_Process + ";";
connection = new SqlConnection(connectionString);
if (connection == null)
{
connection.Open();
}
else if (connection.State == System.Data.ConnectionState.Closed)
{
connection.Open();
}
else if (connection.State == System.Data.ConnectionState.Broken)
{
connection.Close();
connection.Open();
}
return connection;
}
}
public static int ExecuteCommand(string safeSql)
{
SqlCommand cmd = new SqlCommand(safeSql, Connection);
int result = cmd.ExecuteNonQuery();
return result;
connection.Close();
connection.Dispose();
} public static int ExecuteCommand(string sql, params SqlParameter[] values)
{
SqlCommand cmd = new SqlCommand(sql, Connection);
cmd.Parameters.AddRange(values);
return cmd.ExecuteNonQuery();
connection.Close();
connection.Dispose();
} public static string ReturnStringScalar(string safeSql)
{
SqlCommand cmd = new SqlCommand(safeSql, Connection);
try
{
string result = cmd.ExecuteScalar().ToString();
return result;
}
catch (Exception e)
{
return "0";
}
connection.Close();
connection.Dispose();
} public static int GetScalar(string safeSql)
{
SqlCommand cmd = new SqlCommand(safeSql, Connection);
try
{
int result = Convert.ToInt32(cmd.ExecuteScalar());
return result;
}
catch (Exception e)
{
return 0;
}
connection.Close();
connection.Dispose();
}
public static int GetScalar(string sql, params SqlParameter[] values)
{
SqlCommand cmd = new SqlCommand(sql, Connection);
cmd.Parameters.AddRange(values);
int result = Convert.ToInt32(cmd.ExecuteScalar());
return result;
connection.Close();
connection.Dispose();
} public static SqlDataReader GetReader(string safeSql)
{
SqlCommand cmd = new SqlCommand(safeSql, Connection);
SqlDataReader reader = cmd.ExecuteReader();
return reader;
reader.Close();
reader.Dispose();
connection.Close();
} public static SqlDataReader GetReader(string sql, params SqlParameter[] values)
{
SqlCommand cmd = new SqlCommand(sql, Connection);
cmd.Parameters.AddRange(values);
SqlDataReader reader = cmd.ExecuteReader();
return reader;
reader.Close();
reader.Dispose();
connection.Close();
connection.Dispose();
} public static DataTable GetDataSet(string safeSql)
{
DataSet ds = new DataSet();
SqlCommand cmd = new SqlCommand(safeSql, Connection);
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
connection.Close();
connection.Dispose();
return ds.Tables[0];
} public static DataTable GetDataSet(string sql, params SqlParameter[] values)
{
DataSet ds = new DataSet();
SqlCommand cmd = new SqlCommand(sql, Connection);
cmd.Parameters.AddRange(values);
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
connection.Close();
connection.Dispose();
return ds.Tables[0]; }
}
㈣ 倉庫管理sql 語言查詢語句實現
Case 語法錯誤:
應為:
case aa.數量 when aa.數量>0 then aa.數量 else 0 end
另外:
庫存生成,如果想這個做法是不行的,告訴你一個思路:
基礎表應有:入庫單、出庫單;
賬簿應有:數量帳、明細賬、金額帳;
然後使用存儲過程:實現登帳;
最後:在登帳後的賬簿表中進行查詢!
雲馳軟體!
㈤ 列舉sql優化有哪些方式方法 博客園
sql優化的方式有:
1、選擇最有效率的表名順序(只在基於規則的優化器中有效):
ORACLE 的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最後的表(基礎表 driving table)將被最先處理,在FROM子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基礎表。如果有3個以上的表連接查詢, 那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個被其他表所引用的表。
2、WHERE子句中的連接順序:
ORACLE採用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾。
3、SELECT子句中避免使用 『 * 『:
ORACLE在解析的過程中, 會將'*' 依次轉換成所有的列名, 這個工作是通過查詢數據字典完成的, 這意味著將耗費更多的時間 。
4、 減少訪問資料庫的次數:
ORACLE在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變數 , 讀數據塊等。
5、 在SQL*Plus , SQL*Forms和Pro*C中重新設置ARRAYSIZE參數, 可以增加每次資料庫訪問的檢索數據量 ,建議值為200 。
6、 使用DECODE函數來減少處理時間:
使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表。
7、整合簡單,無關聯的資料庫訪問:
如果你有幾個簡單的資料庫查詢語句,你可以把它們整合到一個查詢中(即使它們之間沒有關系)。
㈥ Sql server 安全,性能優化的15條方案
1.1 基本概念 與資料庫技術密切相關的基本概念包括:數據、資料庫、資料庫管理系統和資料庫系統四大概念。1. 數據(Data) 數據是對客觀事物的一種描述,是由能被計算機識別與處理的數值、字元等符號構成的集合,即數據是指描述事物的符號記錄。 廣義地說,數據是一種物理符號的序列,用於記錄事物的情況,是對客觀事物及其屬性進行的一種抽象化及符號化的描述。數據的概念應包括數據的內容和形式兩個方面。數據的內容是指所描述的客觀事物的具體特性,也就是通常所說的數據的「值」;數據的形式則是指數據內容所存儲的具體形式,即數據的「類型」。故此,數據可以用數據類型和值來表示。2. 資料庫(Data Base,DB) 資料庫是指長期存儲在計算機內部、有組織的、可共享的數據集合,即在計算機系統中按一定的數據模型組織、存儲和使用的相關聯的數據集合成為資料庫。 資料庫中的數據按照一定的數據模型組織、描述和存儲,具有較小的冗餘度、較高的數據獨立性、易擴展性、集中性和共享性,以文件的形式存儲在存儲介質上的。資料庫中的數據由資料庫管理系統進行統一管理和控制,用戶對資料庫進行的各種數據操作都是通過資料庫管理系統實現。3. 資料庫管理系統(Data Base Management System,DBMS) 資料庫管理系統是資料庫系統的核心,是為資料庫的建立、使用和維護而配置的軟體,是位於操作系統與用戶之間的一層數據管理軟體。主要功能是對資料庫進行定義、操作、控制和管理。1) 數據定義 數據的定義包括:定義構成資料庫結構的外模式、模式和內模式,定義各個外模式和模式之間的映射,定義模式與內模式之間的映射,定義有關的約束條件。2) 數據處理對數據的處理操作主要包括對資料庫數據的檢索、插入、修改和刪除等基本操作。3) 安全管理 對資料庫的安全管理主要體現在:對資料庫進行並發控制、安全性檢查、完整性約束條件的檢查和執行、資料庫的內部維護(如索引、數據字典的自動維護)等。並且能夠管理和監督用戶的許可權,防止擁護有任何破壞或者惡意的企圖。4) 數據的組織、存儲和管理 負責分類地組織、存儲和管理資料庫數據,確定以何種文件結構和存取方式物理地組織數據,如何實現數據之間的聯系,以便提高存儲空間利用以及提高隨機查找、順序查找、增加、刪除和查改等操作的時間效率。5) 建立和維護資料庫 建立資料庫包括資料庫數據的初始化與數據轉換等。維護資料庫包括資料庫的轉儲與恢復、資料庫的重組織與重構造、性能的監視與分析等。6) 數據通信介面提供與其他軟體系統進行通信的功能。4. 資料庫系統(Data Base System,DBS) 資料庫系統指在計算機系統中引入資料庫後的系統構成,一般有資料庫、資料庫管理系統、應用系統、資料庫管理員和用戶構成。1.2 資料庫系統的特點 資料庫系統的點主要有:數據的結構化、高共享性、低冗餘度、易擴充、較高的獨立性(物理數據獨立、邏輯數據獨立)以及數據由DBMS統一管理和控制(數據的安全性Security保護、數據的完整性Integrity保護、並發Concurrency控制、資料庫恢復Recovery)等。第二章 資料庫性能優化 資料庫作為一種獨立的、有組織、的可共享的數據集合,數據的查詢訪問是數據操作中頻度最高的操作。當數據量和訪問頻率達到一定程度的時候,系統的響應速度就至關重要了,這時候就需要對資料庫數據存儲的結構和方式進行優化,使其滿足系統需要的訪問響應速度。2.1 性能影響因素 常見的影響數據訪問速度的因素,有以下幾種:1. 沒有索引或者沒有用到索引 資料庫索引就像書籍中目錄一樣,使用戶在訪問資料庫數據時,不必遍歷所有數據就可以找到需要的數據。創建索引後,可以保證每行數據的唯一性,極大地提高數據檢索效率,這是一中犧牲空間換取性能的方法。沒有索引或者沒有用到索引是數據訪問速度慢最常見的因素,也是程序設計的一個缺陷所在。2. I/O吞吐量小,形成了瓶頸效應 I/O吞吐量是影響數據訪問速度的客觀因素(硬體因素)。在一定的硬體環境下,利用優化的部署方案可適當提高I/O吞吐量。3. 沒有創建計算列導致查詢不優化 計算列是一個比較特殊的列,不填寫任何設計類型,用戶不可以改變該列的值。計算列的值是通過一定的函數公式等以另一個或多個列的值為輸入值計算出的結果。如果沒相應的計算列,在一些數據查詢的時候需要對已有數據進行計算,從而浪費一部分性能。4. 內存不足 對資料庫數據的查詢訪問毫無疑問會佔用大量的內存空間,當內存不足的情況下,數據的訪問速度會受到明顯的影響甚至訪問出現超時情況,是影響數據訪問速度的客觀因素。5. 網路速度慢 網路速度慢是影響數據訪問速度的客觀因素。可通過提高網路訪問的位寬來解決。6. 查詢出的數據量過大 當查詢出的數據量過大時,內存的佔用、系統時間的佔用等都影響數據訪問的速度。可以採用多次查詢、定位查詢、和查詢數據量控制來解決。7. 鎖或者死鎖 鎖或者死鎖在資料庫數據訪問時會造成訪問者等待時間過程或者永久無法獲取到資源。這是查詢慢最常見的因素之一,是程序設計的缺陷,要盡量避免。8. 返回不必要的行和列 在一般的數據查詢中,都盡可能多的獲取數據信息,這樣造成了不必要的數據遍歷,大大的增加了數據訪問的響應的時間。所以在一般的查詢中,盡量查詢少的行和列,將數據遍歷時間降到最低以滿足數據輸出需求。9. 查詢語句不夠優化 在數據查詢訪問過程中,使用最頻繁的是使用自定義的查詢語句進行數據輸出的。所以編寫優化的查詢語句能夠很大程度上提高數據查詢訪問的速度。2.2 性能優化 資料庫性能優化主要是提高數據訪問的速度,即提高資料庫響應速度的性能指標。性能優化主要分為主觀因素和客觀因素兩部分的優化。這里主要針對影響性能的客觀因素進行優化。2.2.1 主觀因素優化 主觀因素主要是指伺服器的硬體環境。主要優化有以下幾個方面:1、 把數據、日誌、索引放到不同的I/O設備上,增加讀取速度,數據量越大,提高I/O吞吐量越重要;2、 縱向、橫向分割表,減少表的尺寸(sp_spaceuse);3、 升級硬體;4、 提高網路訪問速度;5、 擴大伺服器的內存;配置虛擬內存:虛擬內存大小應基於計算機上並發運行的服務進行配置,一般設置為物理內存的1.5倍;如果安裝了全文檢索功能,並打算運行Microsoft搜索服務以便執行全文索引和查詢,可考慮將虛擬內存大小設置為至少計算機中物理內存的3倍;6、 增加伺服器CPU個數;其中並行處理比串列處理更需要資源。SQL SERVER根據系統負載情況決定最優的並行等級,復雜的需要消耗大量的CPU的查詢適合並行處理。不過更新操作UPDATE、INSERT、DELETE不能進行並行處理。 2.2.2 客觀因素優化 客觀因素主要指的是由於設計和開發中存在的缺陷和漏洞;主要優化有以下幾個方面:1. 優化索引(1) 根據查詢條件建立優化的索引、優化訪問方式,限制結果集的數據量。注意填充因子要適當(最好是使用默認值0)。索引應該盡量小,使用位元組數小的列建里索引(參照索引的創建),不要對有限的幾個值的欄位建立單一索引(如性別欄位)。(2) 如果使用LIKE進行查詢的話,簡單的使用INDEX是不行的,全文索引又太耗費空間。LIKE 『N%』使用索引,LIKE 『%N』不使用索引。用LIKE『%N%』查詢時,查詢耗時和欄位值總長度成正比,所以不能用CHAR類型而採用VARCHAR。對於欄位的值很長的欄位建立全文索引。(3) 重建索引DBCC REINDEX,DBCC INDEXDEFRAG,收縮數據和日誌DBCC SHRINKDB,DBCC SHRINKFILE。設置自動收縮日誌,對與大的資料庫不要設置資料庫自動增長,它會降低伺服器的性能。2. 資料庫部署優化(1) DB SERVER和APPLICATION SERVER分離,OLTP和OLAP分離;(2) 使用分區視圖。分布式分區視圖可用於實現資料庫伺服器聯合體,聯合體是一組分開管理的伺服器,他們互相協作分擔系統的處理負荷。A、在實現分區視圖之前,必須先水平分區表。B、在創建成員表後,在每個伺服器上定義一個分布式分區視圖,並且每個視圖具有相同的名稱。這樣引用分布式分區視圖名的查詢可以在任何一個成員伺服器上運行。系統操作如同每個成員伺服器都有一個原始表的復本一樣,不過每個伺服器上其實只有一個成員表和一個分布式分區視圖。數據的位置對應用程序是透明的。3. 查詢語句優化 T-SQL的寫法上有很大的講究,DBMS處理查詢計劃的過程是:a、查詢語句的詞法、語法檢查;b、將語句提交給DBMS的查詢優化器;c、優化器做代數優化和存取路徑的優化;d、由預編譯模塊生成查詢規劃;e、在合適的時間提交給系統處理執行;f、將執行結果返回給用戶。(1) COMMIT和ROLLBACK的區別:ROLLBACK回滾所有的事務;COMMIT提交當前的事務。在動態語句中寫事務,請將事務寫在外面,如:BEGIN TRAN EXEC(@SQL) COMMIT TRANS或者將動態SQL寫成函數或者存儲過程。(2) 在大數據兩的查詢輸出SELECT語句中盡量不要使用自定義函數,調用自定義函數的函數時系統調用是一個迭代過程,很影響查詢輸出性能的。在查詢欄位時盡可能使用小欄位兩輸出,並在WHERE子句或者使用SELECT TOP 10/1 PERCENT來限制返回的記錄數,使用SET ROWCOUNT來限制操作的記錄數,避免整表掃描。返回不必要的數據,不但浪費了伺服器的I/O資源,加重了網路的負擔,如果表很大的話,在表掃描期間將表鎖住,禁止其他的聯接訪問,後過很嚴重的。(3) SQL的注釋申明對執行查詢輸出沒有任何影響。(4) 使用計算列對數據進行簡單計算,盡量避免在查詢語句中對數據進行運算。(5) 盡可能不使用游標,它會佔用大量的資源。如果需要ROW-BY-ROW地執行,盡量採用非游標技術,如:客戶端循環、臨時表、TABLE變數、子查詢、CASE語句等等。(6) 使用PROFILER來跟蹤查詢,得到查詢所需的時間,找出SQL的問題所在,用索引優化器優化索引。(7) 注意UNION和UNION ALL的區別。在沒有必要的時候不要用DISINCT,它同UNION一樣會降低查詢速度,重復的記錄在查詢里是沒有問題的。(8) 用sp_configure 『query governor cost limit』或者 SET QUERY_COVERNOR_COST_LIMIT來限制查詢消耗的資源。當評估查詢消耗的 資源超出限制時,伺服器自動取消查詢,在查詢之前就扼殺掉。SET LOCKTIME 設置鎖的時間。(9) 不要在WHERE子句中列名加函數,如CONVERT,SUBSTRING等,如果必須用函數的時候,創建計算列在創建索引來替代。NOT IN會多次掃描表,使用EXISTS、NOT EXISTS、IN、LEFT OUTER JOIN來替代,其中EXISTS比IN更快,最慢的NOT操作。(10) 使用QUERY ANALYZER,查看SQL語句的查詢計劃和評估分析是否是優化的SQL。一般20%的代碼佔用了80%的資源,優化的重點就是這些慢的地方。(11) 如果使用了IN或者OR等時發現查詢沒有走索引,使用顯式申明指定索引,如:Select * From FA01(INDEX=IX_SEX) Where AA0107 IN(『01』,『02』)。(12) 在需要對已有數據進行比較復雜計算才能獲得查詢的結果數據時,將需要查詢的結果預先計算好放在表中,查詢的時候在SELECT。(13) 資料庫有一個原則是代碼離數據越近越好,所有有限選擇DEFAULT,依次為RULES,CONSTRAINT,PROCEDURE來編寫程序的質量高,速度快。如果要插入大的二進制到IMAGE列,使用存儲過程,千萬不要用內嵌INSERT直接插入。因為這樣應用程序首先將二進制轉換成字元串,伺服器收到字元後又將他轉換成二進制。存儲過程直接傳入二進制參數即可,處理速度明顯改善,如:CREATE PROCEDURE image_insert @image varbinary as Insert into table(fImage) values(@image)。(14) Between在某些時候比IN速度更快,更快地根據索引找到范圍。由於IN會比較多次,所以有時會慢些。(15) 盡量不要建沒有作用的事務例如產生報表時,浪費資源,只有在必須使用事務時才建立合適的事務。(16) 用OR的字句可以分解成多個查詢,並通過UNION連接多個查詢。速度取決與是否使用索引。如果查詢需要用聯合索引,用UNION ALL執行的效率更高些。(17) 盡量少用視圖,視圖的效率低。對視圖操作比直接對表操作慢,可以用SRORED PROCEDURE來代替。特別是不要用視圖嵌套,嵌套視圖增加了尋找原始資料的難度。視圖是存放在伺服器上的被優化好了的已經產生查詢規劃的SQL。對單表數據檢索時,不要使用指向多表的視圖,否則增加了不必要的系統開銷,查詢也會受到干擾。沒有必要時不要用DISTINCT和ORDER BY,這些動作可以改在客戶端執行,增加了額外的開銷,這同UNION和UNION ALL原理相同。(18) 當使用SELECT INTO和CREATE TABLE時,會鎖住系統表(SYSOBJECTS,SYSINDEXES等),從而阻塞其他的連接的存取。所以千萬不要在事務內部使用。如果經常要用到臨時表時請使用實表或者臨時表變數。盡量少用臨時表,用結果集和TABLE類型的變數來代替。(19) 在使用GROUP BY HAVING子句時,在使用前剔除多餘的行,盡量避免使用HAVING子句剔除行工作。剔除行最優的執行順序是:SELECT的WHERE子句選擇所有合適的行,GROUP
㈦ SQL 資料庫課程設計的思路
可以以一個完整的實例從手,從最基本的地方一點點說明,最後組成一個可以使用的系統(比如圖書管理系統,或是學生點課系統)
㈧ 優化SQL有什麼方法
在資料庫應用系統中編寫可執行的SQL語句可以有多種方式實現,但哪一條是最佳方案卻難以確定。為了解決這一問題,有必要對SQL實施優化。簡單地說,SQL語句的優化就是將性能低下的SQL語句轉換成達到同樣目的的性能更好的SQL語句。
優化SQL語句的原因
資料庫系統的生命周期可以分成: 設計、開發和成品三個階段。在設計階段進行優化的成本最低,收益最大。在成品階段進行優化的成本最高,收益最小。如果將一個資料庫系統比喻成一座樓房,在樓房建好後進行矯正往往成本很高而收效很小(甚至可能根本無法矯正),而在樓房設計、生產階段控制好每塊磚瓦的質量就能達到花費小而見效高的目的。
為了獲得最大效益,人們常需要對資料庫進行優化。資料庫的優化通常可以通過對網路、硬體、操作系統、資料庫參數和應用程序的優化來進行。根據統計,對網路、硬體、操作系統、資料庫參數進行優化所獲得的性能提升全部加起來只佔資料庫應用系統性能提升的40%左右,其餘60%的系統性能提升全部來自對應用程序的優化。許多優化專家甚至認為對應用程序的優化可以得到80%的系統性能提升。因此可以肯定,通過優化應用程序來對資料庫系統進行優化能獲得更大的收益。
對應用程序的優化通常可分為兩個方面: 源代碼的優化和SQL語句的優化。由於涉及到對程序邏輯的改變,源代碼的優化在時間成本和風險上代價很高(尤其是對正在使用中的系統進行優化) 。另一方面,源代碼的優化對資料庫系統性能的提升收效有限,因為應用程序對資料庫的操作最終要表現為SQL語句對資料庫的操作。
對SQL語句進行優化有以下一些直接原因:
1. SQL語句是對資料庫(數據) 進行操作的惟一途徑,應用程序的執行最終要歸結為SQL語句的執行,SQL語句的效率對資料庫系統的性能起到了決定性的作用。
2. SQL語句消耗了70%~90%的資料庫資源。
3. SQL語句獨立於程序設計邏輯,對SQL語句進行優化不會影響程序邏輯,相對於對程序源代碼的優化,對SQL語句的優化在時間成本和風險上的代價都很低。
4. SQL語句可以有不同的寫法,不同的寫法在性能上的差異可能很大。
5. SQL語句易學,難精通。SQL語句的性能往往同實際運行系統的資料庫結構、記錄數量等有關,不存在普遍適用的規律來提升性能。
傳統的優化方法
SQL程序人員在傳統上採用手工重寫來對SQL語句進行優化。這主要依靠DBA或資深程序員對SQL語句執行計劃的分析,依靠經驗,嘗試重寫SQL語句,然後對結果和性能進行比較以試圖找到性能較佳的SQL語句。這種做法存在著以下不足:
1. 無法找出SQL語句的所有可能寫法。很可能花費了大量的時間也無法找到性能較佳的SQL語句。即便找到了某個性能較佳的SQL語句也無法知道是否存在性能更好的寫法。
2. 非常依賴於人的經驗,經驗的多寡往往決定了優化後SQL語句的性能。
3. 非常耗時間。重寫-->校驗正確性-->比較性能,這一循環過程需要大量的時間。
根據傳統的SQL優化工具的功能,人們一般將優化工具分為以下三代產品:
第一代的SQL優化工具是執行計劃分析工具。這類工具對輸入的SQL語句從資料庫提取執行計劃,並解釋執行計劃中關鍵字的含義。
第二代的SQL優化工具只能提供增加索引的建議,它通過對輸入的SQL語句的執行計劃的分析來產生是否要增加索引的建議。這類工具存在著致命的缺點——只分析了一條SQL語句就得出增加某個索引的結論,根本不理會(實際上也無法評估到)增加的索引對整體資料庫系統性能的影響。
第三代工具是利用人工智慧實現自動SQL優化。
人工智慧自動SQL優化
隨著人工智慧技術的發展和在資料庫優化領域應用的深入,在20世紀90年代末優化技術取得了突破性的進展,出現了人工智慧自動SQL優化。人工智慧自動SQL優化的本質就是藉助人工智慧技術,自動對SQL語句進行重寫,找到性能最好的等效SQL語句。LECCO SQL Expert就採用了這種人工智慧技術,其SQL Expert支持Oracle、Sybase、MS SQL Server和IBM DB2資料庫平台。其突出特點是自動優化SQL語句。除此以外,還可以以人工智慧知識庫「反饋式搜索引擎」來重寫SQL語句,並找出所有等效的SQL語句及可能的執行計劃,通過測試運行為應用程序和資料庫自動找到性能最好的SQL語句,提供微秒級的計時; 能夠優化Web應用程序和有大量用戶的在線事務處理中運行時間很短的SQL語句; 能通過比較源SQL和待選SQL的不同之處,為開發人員提供「邊做邊學式訓練」,迅速提高開發人員的SQL編程技能等等。
該工具針對資料庫應用的開發和維護階段提供了數個特別的模塊:SQL語法優化器、PL/SQL集成化開發調試環境(IDE)、掃描器、資料庫監視器等。其核心模塊之一「SQL 語法優化器」的工作原理大致如下:輸入一條源SQL語句,「人工智慧反饋式搜索引擎」對輸入的SQL語句結合檢測到的資料庫結構和索引進行重寫,產生N條等效的SQL語句輸出,產生的N條等效SQL語句再送入「人工智慧反饋式搜索引擎」進行重寫,直至無法產生新的輸出或搜索限額滿,接下來對輸出的SQL語句進行過濾,選出具有不同執行計劃的SQL語句(不同的執行計劃意味著不同的執行效率),最後,對得到的SQL語句進行批量測試,找出性能最好的SQL語句(參見下圖)。
圖 人工智慧自動SQL優化示意圖
LECCO SQL Expert不僅能夠找到最佳的SQL語句,它所提供的「邊做邊學式訓練」還能夠教會開發人員和資料庫管理員如何寫出性能最好的SQL語句。LECCO SQL Expert的SQL語句自動優化功能使SQL的優化變得極其簡單,只要能夠寫出SQL語句,它就能幫開發人員找到最好性能的寫法。
小 結
SQL語句是資料庫應用中一個非常關鍵的部分,它執行性能的高低直接影響著應用程序的運行效率。正因為如此,人們在SQL語句的優化上投入了很大的精力,出現了許多SQL語句優化工具。隨著人工智慧等相關技術的日益成熟, 肯定還會有更多更好的工具出現,這將會給開發人員提供更多的幫助。
㈨ SQL倉儲管理系統的【設計思路】
可以有這幾個功能模塊:登錄、入庫、出庫、查詢統計、系統維護。
1、登錄:用戶名、密碼,獲取用戶的許可權。
2、入庫:登記入庫情況(品名、數量、單價、日期、審核人...)、列印入庫單
3、出庫:登記出庫情況(品名、數量、單價、日期、審核人...)、列印出庫單
4、查詢統計:品名、數量、日期、審核人,列印輸出報表
5、系統維護:用戶管理、物品代碼管理等等。
㈩ 如何通過注入SQL語句獲取網站管理許可權及安全措施
×
loading..
資訊
安全
論壇
下載
讀書
程序開發
資料庫
系統
網路
電子書
微信學院
站長學院
QQ
手機軟體
考試
系統安全|
網站安全|
企業安全|
網路安全|
工具軟體|
殺毒防毒|
加密解密|
首頁 > 安全 > 網站安全 > 正文
如何通過注入SQL語句獲取網站管理許可權及安全措施
2011-04-19
0 個評論
收藏
我要投稿
我們知道網站後台需要驗證用戶的輸入, 如果不這樣做, 用戶甚至可以輸入一些SQL語句操作後台的資料庫,
這么好玩的事情一直沒有真正體驗過. 前幾日學校搞了一個"你最喜歡的輔導員"投票活動, 網站估計是給某個學生團隊做的,
結果經同學破解了這個網站的管理員帳號和密碼, 我遂向他請教了原理, 也了解了他破解的步驟, 自己又實踐了一遍. 感謝經同學,
沒有他我就不知道這些, 也不可能有這篇博客.
本文破解網站的網址是www.2cto.com 本文的內容不適用於這個網站了.我整理了詳細的破解過程跟大家分享, 文中的邏輯比較強, 需要讀者耐心的看. 但文本講述的是破解步驟, 是一般思路, 如果您有疑問, 請留言, 我們交流討論 :)
一 網站是否存在SQL注入漏洞
網站一般包含一張用戶表(用戶名和密碼)和一張管理員信息表(管理員名稱和密碼), 輸入用戶名和密碼之後, 一般做法是後台都會執行一條SQL語句,
查詢有沒有對應的用戶和密碼, 比如SELECT * FROM SomeTable WHERE UserName = $UserName AND
pwd = $pwd, 如果這條語句返回真, 那麼登錄操作就完成了.
試想一下如果在學號和密碼文本框中輸入or=or,
並提交的話, 上面提到的SQL語句就變成了SELECT * FROM SomeTable WHERE UserName = or=or AND
pwd = or=or, 這個語語句變成了一個邏輯表達式, 表達式包含幾段, 分別為:
1. SELECT * FROM SomeTable WHERE UserName = (假)
or
2. = (真)
or
3. (假)
and
4. pwd = (假)
or
5. = (真)
or
6. (假)
最後整個邏輯表達式為0|1|0&0|1|0, 這個結果為真(在執行到"0|1|..."的時候整個表達式省略號中的就不計算了, 因為"或"前面已經是真), 因此可以登錄成功, 事實上也登錄成功了.
二 破解後台資料庫的原理
在用戶名和密碼的文本框中輸入or=or, 截至上面所示的第2步, 表達式值為真,
因為後面緊接了一個"或", 所以無論在這後面的表達式是什麼, "真或者假""真或者真"都是為真的. 關鍵就是or=or中間的那個=,
=表示一個字元, 永遠為真. 如果我們將這個=改成某個SQL表達式, 如果這個表達式為真, 那麼整個表達式就為真.
後面的幾個步驟要求用戶名和密碼文本框中都輸入同樣的文本, 原因是: 後台的語句格式可能是SELECT * FROM SomeTable
WHERE UserName = $UserName AND pwd = $pwd, 也有可能是SELECT * FROM SomeTable
WHERE pwd = $pwd AND UserName = $UserName, 無論哪一種情況, 只要用戶名和密碼都輸入的文本是一樣的,
只要文本中包含的SQL表達式為真, 那麼整個表達式就為真. 這樣寫帶來的另一個好處是復制粘貼很方便.
通過寫一些SQL表達式來一次一次的測試出資料庫里的內容.
三 獲取後台資料庫的表名
如果將表達式替換為(SELECT COUNT(*) FROM 表名)<>0,
這個表達式用來獲取一個表中有多少條記錄, 需要做的就是猜這個表名是什麼, 猜中了的話, 那麼這個表中的記錄條數肯定就不會等於0,
那麼這個表達式的值就是真的. 常用的表名也就是那麼一些, 一個個的代進去試, 最後發現有個叫做admin的表, 它的欄位不為空. 很顯然,
這個表是用來存放管理員信息的.
四 獲取後台資料庫表的欄位名
現在已經知道這個表叫做admin了, 接下來想辦法得到這個表中的欄位.
把表達式替換成(SELECT COUNT(*) FROM admin WHERE LEN(欄位名)>0)<>0,
這個表達式用來測試admin這個表中是否包含這個欄位. LEN(欄位名)>0表示這個欄位的長度大於0, 在這個欄位存在的情況下,
LEN(欄位名)>0是始終為真的. 如果包含的話這個欄位的話, 整條SELECT語句返回的數字肯定不為0, 也就是說整個表達式為真,
從而得到欄位名.
按照這樣的方法, 靠猜共得出了三個很關鍵的欄位:id, admin, pass.
五 獲取欄位的長度
目前已得到的信息是有個admin表, 表中有id, admin, pass欄位. 後台中存儲用戶名和密碼, 常規做法是存儲它們進行MD5加密後的值(32位), 現在測試一下是不是這樣.
把表達式替換為(SELECT COUNT(*) FROM admin WHERE LEN(欄位名)=32)<>0, 將admin和pass代進去結果是真, 說明後台存儲管理員帳號和密碼用的是加密後32位的欄位.
六 獲取管理員帳號和密碼
MD5加密後的字元串包含32位, 且只可能是由0-9和A-F這些字元組成.
1. 獲取管理員帳號
將表達式改成(SELECT COUNT(*) FROM admin WHERE LEFT(admin,1)=A)>0,
意思是我猜測某個adimin帳號的第一個字元是A, 如果成功則表達式成立. 失敗的話, 把A換成0-9和B-F中的任意字元繼續試, 知道成功.
如果成功了, 我再繼續猜這個帳號的第二個字元, 假如第一個字元是5, 我猜測第二個字元是A, 那將表達式改成(SELECT COUNT(*)
FROM admin WHERE LEFT(admin,2)=5A)>0. 可以發現字元串中LEFT()函數中的1變成了2,
另外5A代碼左邊兩個字元是5A, 其中5已經確定下來了. 就這樣重復不斷的猜, 直到得到整個32位的MD5加密後的字元串.
2. 獲取該帳號對應的的id
為什麼需要獲取該帳號對應的id? 原因如下: 按照上一條是可以得到帳號和密碼的, 但一張表中可以有若干個管理員帳號和密碼, 怎麼對應起來呢? 需要通過id. 一個id對應一條記錄, 一條記錄只有一對匹配的帳號和密碼.
將表達式改成(SELECT COUNT(*) FROM admin WHERE LEFT(admin,1)=5 AND id=1)>0,
上一條假設了某帳號第一個字元是5, 只要這個表達式中的"AND id = 1"正確, 那麼就可以得知該帳號的id是1. 如果不是1,
換成其它的數字一個個的試一試.
3. 獲取帳號對應的密碼
現在已經猜出了某管理員的帳號,
並且知道對應的id是多少(假設得出來是4), 現在只要得到該條記錄中記錄的密碼是什麼. 同理, 將表達式改成(SELECT COUNT(*)
FROM admin WHERE LEFT(pass,1)=A AND id=4)>0, 注意id已經是知道了的4,
現在要一個個的猜pass中從第1個到第32個字元是什麼, 方法同"獲取管理員帳號"方法. 最後可以得到一個32位的MD5加密後的字元串(密碼).
*注: 如果嫌手工得到每個字元是什麼太麻煩, 可以自己用C#寫一個程序, 模擬一下登錄, 通過控制一個循環, 可以很快得到結果.
七 將MD5加密後的帳號和密碼轉成明文
網上有一些網站資料庫里存儲了海量(幾萬億條)的MD5加密後的暗文對應的明文, 只需輸入你需要查找的MD5加密後的字元串就可以查看到明文是什麼.