一、先來熟悉一下將要使用的對象方法:
用來獲取上一個頁面傳 遞過來的數據一般是使用Request對象。同樣的,我們也可以使用Request對象 來獲取上傳上來的文件數據,使用的方法是Request.BinaryRead()。
要從資料庫中讀出來圖片的數據顯示到網頁上面要用到的方法是:Request.BinaryWrite()。
二、在得到了圖片的數據,要保存到資料庫中的時候,不可以直接使用Insert語句對資料庫進行操作,而是要使用ADO的AppendChunk方法。
同樣的,讀出資料庫中的圖片數據,要使用GetChunk方法。
各個方法的具體語法如下:
*Request.BinaryRead語法:
variant=Request.BinaryRead(count)
參數
variant
返回值保存著從客戶端讀取到數據。
count
指明要從客戶端讀取的數據量大小,這個值小於或者等於使用方法
Request.TotalBytes得到的數據量。
*Request.BinaryWrite語法:
Request.BinaryWritedata
參數
data
要寫入到客戶端瀏覽器中的數據包。
*Request.TotalBytes語法:
variant=Request.TotalBytes
參數
variant
返回從客戶端讀取到數據量的位元組數。
*AppendChunk語法
將數據追加到大型文本、二進制數據Field或Parameter對象。
object.AppendChunkData
參數
objectField或Parameter對象
Data變體型,包含追加到對象中的數據。
說明
使用Field或Parameter對象的AppendChunk方法可將長二進制或字元數
據填寫到對象中。在系統內存有限的情況下,可以使用AppendChunk方法對長
整型值進行部分而非全部的操作。
*GetChunk語法
返回大型文本或二進制數據Field對象的全部或部分內容。
variable=field.GetChunk(Size)
返回值
返回變體型。
參數
Size長整型表達式,等於所要檢索的位元組或字元數。
說明
使用Field對象的GetChunk方法檢索其部分或全部長二進制或字元數據。
在系統內存有限的情況下,可使用GetChunk方法處理部分而非全部的長整型
值。
GetChunk調用返回的數據將賦給「變數」。如果Size大於剩餘的數據,則
GetChunk僅返回剩餘的數據而無需用空白填充「變數」。如果欄位為空,則
GetChunk方法返回Null。
每個後續的GetChunk調用將檢索從前一次GetChunk調用停止處開始的數
據。但是,如果從一個欄位檢索數據然後在當前記錄中設置或讀取另一個欄位
的值,ADO將認為已從第一個欄位中檢索出數據。如果在第一個欄位上再次調
用GetChunk方法,ADO將把調用解釋為新的GetChunk操作並從記錄的起始
處開始讀取。如果其他Recordset對象不是首個Recordset對象的副本,則
訪問其中的欄位不會破壞GetChunk操作。
如果Field對象的Attributes屬性中的adFldLong位設置為True,則可
以對該欄位使用GetChunk方法。
如果在Field對象上使用Getchunk方法時沒有當前記錄,將產生錯誤3021
(無當前記錄)。
三、設計資料庫,作為測試的資料庫結構如下(Access97):
欄位名稱類型描述
id自動編號主鍵值
imgOLE對象用來保存圖片數據
對於在MSSQLServer7中,對應的結構如下:
欄位名稱類型描述
idint(Identity)主鍵值
imgimage用來保存圖片數據
四、正式編寫純ASP代碼上傳部分了,首先,有一個提供給用戶的上傳界面,可以讓用戶選擇要上傳的圖片。代碼如下(upload.htm):
<html>
<body>
<center>
<formname="mainForm"enctype="multipart/form-data"
action="process.asp"method=post>
<inputtype=filename=mefile><br>
<inputtype=submitname=okvalue="OK">
</form>
</center>
</body>
</html>
注意代碼中黑色斜體的部分,一定要在Form中有這個屬性,否則,將無
法得到上傳上來的數據。
五、接下來,要在process.asp中對從瀏覽器中獲取的數據進行必要的處理,因為在process.asp中獲取到的數據不僅僅包含了想要的上傳上來的圖片的數據,也包含了其他的無用的信息,需要剔除冗餘數據,並將處理過的圖片數據保存到資料庫中,這里以Access97為例。具體代碼如下(process.asp):
<%
response.buffer=true
formsize=request.totalbytes
formdata=request.binaryread(formsize)
bncrlf=chrB(13)&chrB(10)
divider=leftB(formdata,clng(instrb(formdata,bncrlf))-1)
datastart=instrb(formdata,bncrlf&bncrlf)+4
dataend=instrb(datastart+1,formdata,divider)-datastart
mydata=midb(formdata,datastart,dataend)setconnGraph=server.CreateObject("ADODB.connection")
connGraph.ConnectionString="driver={MicrosoftAccessDriver(*.mdb)};DBQ="&
server.MapPath("images.mdb")&";uid=;PWD=;"
connGraph.Opensetrec=server.createobject("ADODB.recordset")
rec.Open"SELECT*FROM[images]whereidisnull",connGraph,1,3
rec.addnew
rec("img").appendchunkmydata
rec.update
rec.close
setrec=nothing
setconnGraph=nothing
%>
六、這樣就把上傳來的圖片保存到了名為images.mdb的資料庫中了,剩下的工作就是要將資料庫中的圖片數據顯示到網頁上面了。
一般在HTML中,顯示圖片都是使用<IMG>標簽,也就是<IMGSRC="圖片路徑">,但是圖片是保存到了資料庫中,「圖片路徑」是什麼呢?呵呵,其實這個SRC屬性除了指定路徑外,也可以這樣使用哦:
<IMGSRC="showimg.asp?id=xxx">
所以,要做的就是在showimg.asp中從資料庫中讀出來符合條件的數據,並返回到SRC屬性中就可以了,具體代碼如下(showimg.asp):
<%
setconnGraph=server.CreateObject("ADODB.connection")
connGraph.ConnectionString="driver={MicrosoftAccessDriver(*.mdb)};DBQ="&
server.MapPath("images.mdb")&";uid=;PWD=;"
connGraph.Open
setrec=server.createobject("ADODB.recordset")
strsql="selectimgfromimageswhereid="&trim(request("id"))
rec.openstrsql,connGraph,1,1
Response.ContentType="image/*"
Response.BinaryWriterec("img").getChunk(7500000)
rec.close
setrec=nothing
setconnGraph=nothing
%>
七、注意在輸出到瀏覽器之前一定要指Response.ContentType="image/*",以便正常顯示圖片。最後要注意的地方是,我的process.asp中作的處理沒有考慮到第一頁(upload.htm)中還有其他數據,比如<INPUTtype=tesxtname=userid>等等,如果有這些項目,process.asp就要注意處理掉不必要的數據。
2. 請問SQL中視圖與查詢的區別
SQL中視圖與查詢的區別為:功能不同、歸屬不同、數據來源不同。
一、功能不同
1、視圖:視圖可以更新欄位內容並返回原表。
2、查詢:查詢文件中的記錄數據不能修改。
二、歸屬不同
1、視圖:視圖不是一個獨立的文件,它保存在資料庫中。
2、查詢:查詢是一個獨立的文件,不屬於資料庫。
三、數據來源不同
1、視圖:視圖的數據來源可以是本地數據源,也可以是遠程數據源。
2、查詢:查詢的數據來源只有本地數據源,不能訪問遠程數據源。
3. 資料庫基礎詳解:存儲過程、視圖、游標、SQL語句優化以及索引
寫在文章前:本系列文章用於博主自己歸納復習一些基礎知識,同時也分享給可能需要的人,因為水平有限,肯定存在諸多不足以及技術性錯誤,請大佬們及時指正。
存儲過程 是事先經過編譯並存儲在資料庫中的一段SQL語句的集合。想要實現相應的功能時,只需要調用這個存儲過程就行了(類似於函數,輸入具有輸出參數)。
優點 :
缺點 :
Delete用來刪除表的全部或者部分數據,執行delete之後,用戶需要提交之後才會執行,會觸發表上的DELETE觸發器(包含一個OLD的虛擬表,可以只讀訪問被刪除的數據),DELETE之後表結構還在,刪除很慢,一行一行地刪,因為會記錄日誌,可以利用日誌還原數據;
Truncate刪除表中的所有數據,這個操作不能回滾,也不會觸發這個表上的觸發器。操作比DELETE快很多(直接把表drop掉,再創建一個新表,刪除的數據不能找回)。如果表中有自增(AUTO_INCREMENT)列,則重置為1。
Drop命令從資料庫中刪除表,所有的數據行,索引和約束都會被刪除。不能回滾,不會觸發觸發器。
觸發器(TRIGGER)是由事件(比如INSERT/UPDATE/DELETE)來觸發運行的操作(不能被直接調用,不能接收參數)。在資料庫里以獨立的對象存儲,用於保證數據完整性(比如可以檢驗或轉換數據)。
約束(Constraint)類型:
從資料庫的基本表中通過查詢選取出來的數據組成的虛擬表(資料庫中只存放視圖的定義,而不存放視圖的數據)。可以對其進行增/刪/改/查等操作。視圖是對若干張基本表的引用,一張虛表,查詢語句執行的結果,不存儲具體的數據(基本表數據發生了改變,視圖也會跟著改變)。
可以跟基本表一樣,進行增刪改查操作( 增刪改操作有條件限制,一般視圖只允許查詢操作 ),對視圖的增刪改也會影響原表的數據。 它就像一個窗口,透過它可以看到資料庫中自己感興趣的數據並且操作它們。 好處:
用於定位在查詢返回的結果集的特定行,以對特定行進行操作。使用游標可以方便地對結果集進行移動遍歷,根據需要滾動或對瀏覽/修改任意行中的數據。主要用於互動式應用。它是一段私有的SQL工作區,也就是一段內存區域,用於暫時存放受SQL語句影響的數據,簡單來說,就是將受影響的數據暫時放到了一個內存區域的虛表當中,這個虛表就是游標。
游標是一種能從包括多條數據記錄的結果集中每次提取一條記錄的機制。即游標用來逐行讀取結果集。游標充當指針的作用。盡管游標能遍歷結果中的所有行,但他一次只指向一行。
游標的一個常見用途就是保存查詢結果,以便以後使用。游標的結果集是由SELECT語句產生,如果處理過程需要重復使用一個記錄集,那麼創建一次游標而重復使用若干次,比重復查詢資料庫要快的多。通俗來說,游標就是能在sql的查詢結果中,顯示某一行(或某多行)數據,其查詢的結果不是數據表,而是已經查詢出來的結果集。
簡單來說:游標就是在查詢出的結果集中進行選擇性操作的工具。
讓緩存更高效。對於連接查詢,如果其中一個表發生變化,那麼整個查詢緩存就無法使用。而分解後的多個查詢,即使其中一個表發生變化,對其它表的查詢緩存依然可以使用。分解成多個單表查詢,這些單表查詢的緩存結果更可能被其它查詢使用到,從而減少冗餘的查詢。減少鎖競爭。
索引是對資料庫表中一列或多列的值進行排序的一種結構(說明是在列上建立的),使用索引可快速訪問資料庫表中的特定信息。如果想按特定職員的姓來查找他或她,則與在表中搜索所有的行相比,索引有助於更快地獲取信息。索引的一個主要目的就是加快檢索表中數據,亦即能協助信息搜索者盡快的找到符合限制條件的記錄ID的輔助數據結構。
當表中有大量記錄時,若要對表進行查詢,第一種搜索信息方式是全表搜索,是將所有記錄一一取出,和查詢條件進行一一對比,然後返回滿足條件的記錄,這樣做會消耗大量資料庫系統時間,並造成大量磁碟I/O操作。第二種就是在表中建立索引,然後在索引中找到符合查詢條件的索引值,最後通過保存在索引中的ROWID(相當於頁碼)快速找到表中對應的記錄。
例如這樣一個查詢:select * from table1 where id=10000。如果沒有索引,必須遍歷整個表,直到ID等於10000的這一行被找到為止。有了索引之後(必須是在ID這一列上建立的索引),即可在索引中查找。由於索引是經過某種演算法優化過的,因而查找次數要少的多。可見,索引是用來定位的。
從應用上分, 主鍵索引(聚集) , 唯一索引(聚集/非聚集) , 普通索引 , 組合索引 , 單列索引和全文索引
4. sql如何創建視圖
使用create view語句就可以創建視圖了,具體語句如下:
create view viewname as select * from Tab_EdsProd(Tab_EdsProd是表的名字)where (後面可以接一線限制的條件)。
刪除視圖:drop view viewname。
(4)在sql語句中識圖擴展閱讀:
視圖的作用:
1、使用視圖,可以定製用戶數據,聚焦特定的數據。
2、使用視圖,可以簡化數據操作。
3、使用視圖,基表中的數據就有了一定的安全性。因為視圖是虛擬的,物理上是不存在的,只是存儲了數據的集合,我們可以將基表中重要的欄位信息,可以不通過視圖給用戶。
視圖是動態的數據的集合,數據是隨著基表的更新而更新。同時,用戶對視圖,不可以隨意的更改和刪除,可以保證數據的安全性。
4、使用視圖可以合並分離的數據,創建分區視圖。
參考資料:網路-sql語句大全
5. SQL語言的實體實體,屬性,碼,E-R圖是什麼
E-R的全拼是:entity-relation,即實體關系圖!類和表裡面的欄位屬性對應起來。
6. Sql語句解析過程
為了將用戶寫的SQL文本轉化為Oracle認識的且可執行的語句 這個過程就叫做解析過程 解析分為硬解析和軟解析 一條SQL語句在第一次被執行時必須進行硬解析
當客戶端發出一條SQL語句(也可以是一個存儲過程或者一個匿名PL/SQL塊)進入shared pool時(注意 我們從前面已經知道 Oracle對這些SQL不叫做SQL語句 而是稱為游標 因為Oracle在處理SQL時 需要很多相關的輔助信息 這些輔助信息與SQL語句一起組成了游標) Oracle首先將SQL文本轉化為ASCII值 然後根據hash函數計算其對應的hash值(hash_value) 根據計算出的hash值到library cache中找到對應的bucket 然後比較bucket里是否存在該SQL語句
如果不存在 則需要按照我們前面所描述的 獲得shared pool latch 然後在shared pool中的可用chunk鏈表(也就是bucket)上找到一個可用的chunk 之後釋放shared pool latch 在獲得了chunk以後 這塊chunk就可以認為是進入了library cache 接下來 進行硬解析過程 硬解析包括以下幾個步驟
對SQL語句進行文法檢查 看是否有文法錯誤 比如沒有寫from select拼寫錯誤等 如果存在文法錯誤 則退出解析過程
到數據字典里校驗SQL語句涉及的對象和列是否都存在 如果不存在 則退出解析過程 這個過程會載入dictionary cache
將對象進行名稱轉換 比如將同名詞翻譯成實際的對象等 比如select * from t中 t是一個同名詞 指向hr t 於是Oracle將t轉換為hr t 如果轉換失敗 則退出解析過程
檢查發出SQL語句的用戶是否具有訪問SQL語句里所引用的對象的許可權 如果沒有許可權 則退出解析過程
通過優化器創建一個最優的執行計劃 這個過程會根據數據字典里記錄的對象的統計信息 來計算最優的執行計劃 這一步牽涉大量數學運算 是最消耗CPU資源的
將該游標所產生的執行計劃 SQL文本等裝載進library cache的heap中
在硬解析的過程中 進程會一直持有library cache latch 直到硬解析結束為止 硬解析結束以後 會為SQL語句產生兩個游標 一個是父游標 另一個是子游標 父游標里主要包含兩種信息 SQL文本以及優化目標(optimizer goal) 父游標在第一次打開時被鎖定 直到其他所有的session都關閉該游標後才被解鎖 當父游標被鎖定的時候是不能被交換出library cache的 只有在解鎖以後才能被交換出library cache 父游標被交換出內存時 父游標對應的所有子游標也被交換出library cache 子游標包括游標所有的信息 比如具體的執行計劃 綁定變數等 子游標隨時可以被交換出library cache 當子游標被交換出library cache時 Oracle可以利用父游標的信息重新構建出一個子游標來 這個過程叫reload 可以使用下面的方式來確定reload的比率
select *sum(reloads)/sum(pins) Reload_Ratio from v$librarycache;
一個父游標可以對應多個子游標 子游標具體的個數可以從視圖v$sqlarea的version_count欄位體現出來 而每個具體的子游標則全都在視圖v$sql里體現 當具體綁定變數的值與上次綁定變數的值有較大差異(比如上次執行的綁定變數值的長度是 位 而這次執行綁定變數的值的長度是 位)時或者當SQL語句完全相同 但是所引用的表屬於不同的用戶時 都會創建一個新的子游標
如果在bucket中找到了該SQL語句 則說明該SQL語句以前運行過 於是進行軟解析 軟解析是相對於硬解析而言的 如果解析過程中 可以從硬解析的步驟中去掉一個或多個的話 這樣的解析就是軟解析 軟解析分為以下三種類型
第一種是某個session發出的SQL語句與library? cache里其他session發出的SQL語句一致 這時 該解析過程中可以去掉硬解析中的 和 但是仍然要進行硬解析過程中的 也就是表名和列名檢查 名稱轉換和許可權檢查
* 第二種是某個session發出的SQL語句是該session之前發出的曾經執行過的SQL語句 這時 該解析過程中可以去掉硬解析中的 和 這四步 但是仍然要進行許可權檢查 因為可能通過grant改變了該session用戶的許可權
* 第三種是當設置了初始化參數session_cached_cursors時 當某個session第三次執行相同的SQL時 則會把該SQL語句的游標信息轉移到該session的PGA里 這樣 該session以後再執行相同的SQL語句時 會直接從PGA里取出執行計劃 從而跳過硬解析的所有步驟 這種情況下 是最高效的解析方式 但是會消耗很大的內存
我們舉一個例子來說明解析SQL語句的過程 在該測試中 綁定變數名稱相同 但是變數類型不同時 所出現的解析情況 如下所示
首先 執行下面的命令 清空shared pool里所有的SQL語句
SQL> alter system flush shared_pool;
然後 定義一個數值型綁定變數 並為該綁定變數賦一個數值型的值以後 執行具體的查詢語句
SQL> variable v_obj_id number;
SQL> exec :v_obj_id := ;
SQL> select object_id object_name from sharedpool_test
where object_id=:v_obj_id;
OBJECT_ID OBJECT_NAME
AGGXMLIMP
接下來 定義一個字元型的綁定變數 變數名與前面相同 為該綁定變數賦一個字元型的值以後 執行相同的查詢
SQL> variable v_obj_id varchar ( );
SQL> exec :v_obj_id := ;
SQL> select object_id object_name from sharedpool_test
where object_id=:v_obj_id;
OBJECT_ID OBJECT_NAME
AGGXMLIMP
然後我們到視圖v$sqlarea里找到該SQL的父游標的信息 並到視圖v$sql里找該SQL的所有子游標的信息
SQL> select sql_text version_count from v$sqlarea where
sql_text like %sharedpool_test% ;
SQL_TEXT
VERSION_COUNT
select object_id object_name from sharedpool_test where
object_id=:v_obj_id
SQL> select sql_text child_address address from v$sql
where sql_text like %sharedpool_test% ;
SQL_TEXT
CHILD_ADDRESS ADDRESS
select object_id object_name from sharedpool_test where
object_id=:v_obj_id F
B D
select object_id object_name from sharedpool_test where
object_id=:v_obj_id FC
B D
從記錄父游標的視圖v$sqlarea的version_count列可以看到 該SQL語句有 個子游標 而從記錄子游標的視圖v$sql里可以看到 該SQL文本確實有兩條記錄 而且它們的SQL文本所處的地址(ADDRESS列)也是一樣的 但是子地址(CHILD_ADDRESS)卻不一樣 這里的子地址實際就是子游標所對應的heap 的句柄
lishixin/Article/program/Oracle/201311/18653
7. SQL語句怎樣查詢一個范圍
SQL語句通過「BETWEEN…AND…」語法來查詢一個范圍。
WHERE子句設置查詢條件,過濾掉不需要的數據行。其范圍運算符「BETWEEN…AND…」表示表達式值是否在指定的范圍內,類似的「NOT BETWEEN…AND…」表示表達式值是否不在指定的范圍內。
例如:SELECT * FROM user WHERE age BETWEEN 10 AND 30,用於查詢出user表中age值介於10~30間的數據記錄。
(7)在sql語句中識圖擴展閱讀:
SQL中WHERE子句其它運算符:
1、比較運算符
>、>=、=、<、<=、<>
2、列表運算符
IN (項1,項2……)
NOT IN (項1,項2……)
3、模式匹配符
LIKE、NOT LIKE
4、空值判斷符
IS NULL、IS NOT NULL
5、邏輯運算符
NOT、AND、OR
8. 如何使用SQL
掌握SQL四條最基本的數據操作語句:Insert,Select,Update和Delete。
練掌握SQL是資料庫用戶的寶貴財 富。掌握四條最基本的數據操作語句—SQL的核心功能—來依次介紹比較操作符、選擇斷言以及三值邏輯。當你完成這些學習後,顯然你已經開始算是精通SQL了。
在我們開始之前,先使用CREATE TABLE語句來創建一個表(如圖1所示)。DDL語句對資料庫對象如表、列和視進行定義。它們並不對表中的行進行處理,這是因為DDL語句並不處理資料庫中實際的數據。這些工作由另一類SQL語句—數據操作語言(DML)語句進行處理。
SQL中有四種基本的DML操作:INSERT,SELECT,UPDATE和DELETE。由於這是大多數SQL用戶經常用到的,我們有必要在此對它們進行一一說明。在圖1中我們給出了一個名為EMPLOYEES的表。其中的每一行對應一個特定的雇員記錄。請熟悉這張表,我們在後面的例子中將要用到它。
INSERT語句
用戶可以用INSERT語句將一行記錄插入到指定的一個表中。例如,要將雇員John Smith的記錄插入到本例的表中,可以使用如下語句:
INSERT INTO EMPLOYEES VALUES
('Smith','John','1980-06-10',
'Los Angles',16,45000);
通過這樣的INSERT語句,系統將試著將這些值填入到相應的列中。這些列按照我們創建表時定義的順序排列。在本例中,第一個值「Smith」將填到第一個列LAST_NAME中;第二個值「John」將填到第二列FIRST_NAME中……以此類推。
我們說過系統會「試著」將值填入,除了執行規則之外它還要進行類型檢查。如果類型不符(如將一個字元串填入到類型為數字的列中),系統將拒絕這一次操作並返回一個錯誤信息。
如果SQL拒絕了你所填入的一列值,語句中其他各列的值也不會填入。這是因為SQL提供對事務的支持。一次事務將資料庫從一種一致性轉移到另一種一致性。如果事務的某一部分失敗,則整個事務都會失敗,系統將會被恢復(或稱之為回退)到此事務之前的狀態。
回到原來的INSERT的例子,請注意所有的整形十進制數都不需要用單引號引起來,而字元串和日期類型的值都要用單引號來區別。為了增加可讀性而在數字間插入逗號將會引起錯誤。記住,在SQL中逗號是元素的分隔符。
同樣要注意輸入文字值時要使用單引號。雙引號用來封裝限界標識符。
對於日期類型,我們必須使用SQL標准日期格式(yyyy-mm-dd),但是在系統中可以進行定義,以接受其他的格式。當然,2000年臨近,請你最好還是使用四位來表示年份。
既然你已經理解了INSERT語句是怎樣工作的了,讓我們轉到EMPLOYEES表中的其他部分:
INSERT INTO EMPLOYEES VALUES
('Bunyan','Paul','1970-07-04',
'Boston',12,70000);
INSERT INTO EMPLOYEES VALUES
('John','Adams','1992-01-21',
'Boston',20,100000);
INSERT INTO EMPLOYEES VALUES
('Smith','Pocahontas','1976-04-06',
'Los Angles',12,100000);
INSERT INTO EMPLOYEES VALUES
('Smith','Bessie','1940-05-02',
'Boston',5,200000);
INSERT INTO EMPLOYEES VALUES
('Jones','Davy','1970-10-10',
'Boston',8,45000);
INSERT INTO EMPLOYEES VALUES
('Jones','Indiana','1992-02-01',
'Chicago',NULL,NULL);
在最後一項中,我們不知道Jones先生的工薪級別和年薪,所以我們輸入NULL(不要引號)。NULL是SQL中的一種特殊情況,我們以後將進行詳細的討論。現在我們只需認為NULL表示一種未知的值。
有時,像我們剛才所討論的情況,我們可能希望對某一些而不是全部的列進行賦值。除了對要省略的列輸入NULL外,還可以採用另外一種INSERT語句,如下:
INSERT INTO EMPLOYEES(
FIRST_NAME, LAST_NAME,
HIRE_DATE, BRANCH_OFFICE)
VALUE(
'Indiana','Jones',
'1992-02-01','Indianapolis');
這樣,我們先在表名之後列出一系列列名。未列出的列中將自動填入預設值,如果沒有設置預設值則填入NULL。請注意我們改變了列的順序,而值的順序要對應新的列的順序。如果該語句中省略了FIRST_NAME和LAST_NAME項(這兩項規定不能為空),SQL操作將失敗。
讓我們來看一看上述INSERT語句的語法圖:
INSERT INTO table
[(column { ,column})]
VALUES
(columnvalue [{,columnvalue}]);
和前一篇文章中一樣,我們用方括弧來表示可選項,大括弧表示可以重復任意次數的項(不能在實際的SQL語句中使用這些特殊字元)。VALUE子句和可選的列名列表中必須使用圓括弧。
SELECT語句
SELECT語句可以從一個或多個表中選取特定的行和列。因為查詢和檢索數據是資料庫管理中最重要的功能,所以SELECT語句在SQL中是工作量最大的部分。實際上,僅僅是訪問資料庫來分析數據並生成報表的人可以對其他SQL語句一竅不通。
SELECT語句的結果通常是生成另外一個表。在執行過程中系統根據用戶的標准從資料庫中選出匹配的行和列,並將結果放到臨時的表中。在直接SQL(direct SQL)中,它將結果顯示在終端的顯示屏上,或者將結果送到列印機或文件中。也可以結合其他SQL語句來將結果放到一個已知名稱的表中。
SELECT語句功能強大。雖然表面上看來它只用來完成本文第一部分中提到的關系代數運算「選擇」(或稱「限制」),但實際上它也可以完成其他兩種關系運算—「投影」和「連接」,SELECT語句還可以完成聚合計算並對數據進行排序。
SELECT語句最簡單的語法如下:
SELECT columns FROM tables;
當我們以這種形式執行一條SELECT語句時,系統返回由所選擇的列以及用戶選擇的表中所有指定的行組成的一個結果表。這就是實現關系投影運算的一個形式。
讓我們看一下使用圖1中EMPLOYEES表的一些例子(這個表是我們以後所有SELECT語句實例都要使用的。而我們在圖2和圖3中給出了查詢的實際結果。我們將在其他的例子中使用這些結果)。
假設你想查看雇員工作部門的列表。那下面就是你所需要編寫的SQL查詢:
SELECT BRANCH_OFFICE FROM EMPLOYEES;
以上SELECT語句的執行將產生如圖2中表2所示的結果。
由於我們在SELECT語句中只指定了一個列,所以我們的結果表中也只有一個列。注意結果表中具有重復的行,這是因為有多個雇員在同一部門工作(記住SQL從所選的所有行中將值返回)。要消除結果中的重復行,只要在SELECT語句中加上DISTINCT子句:
SELECT DISTINCT BRANCH_OFFICE
FROM EMPLOYEES;
這次查詢的結果如表3所示。
現在已經消除了重復的行,但結果並不是按照順序排列的。如果你希望以字母表順序將結果列出又該怎麼做呢?只要使用ORDER BY子句就可以按照升序或降序來排列結果:
SELECT DISTINCT BRANCH_OFFICE
FROM EMPLOYEES
ORDER BY BRANCH_OFFICE ASC;
這一查詢的結果如表4所示。請注意在ORDER BY之後是如何放置列名BRANCH _OFFICE的,這就是我們想要對其進行排序的列。為什麼即使是結果表中只有一個列時我們也必須指出列名呢?這是因為我們還能夠按照表中其他列進行排序,即使它們並不顯示出來。列名BRANCH_ OFFICE之後的關鍵字ASC表示按照升序排列。如果你希望以降序排列,那麼可以用關鍵字DESC。
同樣我們應該指出ORDER BY子句只將臨時表中的結果進行排序;並不影響原來的表。
假設我們希望得到按部門排序並從工資最高的雇員到工資最低的雇員排列的列表。除了工資括弧中的內容,我們還希望看到按照聘用時間從最近聘用的雇員開始列出的列表。以下是你將要用到的語句:
SELECT BRANCH_OFFICE,FIRST_NAME,
LAST_NAME,SALARY,HIRE_DATE
FROM EMPLOYEES
ORDER BY SALARY DESC,
HIRE_DATE DESC;
這里我們進行了多列的選擇和排序。排序的優先順序由語句中的列名順序所決定。SQL將先對列出的第一個列進行排序。如果在第一個列中出現了重復的行時,這些行將被按照第二列進行排序,如果在第二列中又出現了重復的行時,這些行又將被按照第三列進行排序……如此類推。這次查詢的結果如表5所示。
將一個很長的表中的所有列名寫出來是一件相當麻煩的事,所以SQL允許在選擇表中所有的列時使用*號:
SELECT * FROM EMPLOYEES;
這次查詢返回整個EMPLOYEES表,如表1所示。
下面我們對開始時給出的SELECT語句的語法進行一下更新(豎直線表示一個可選項,允許在其中選擇一項。):
SELECT [DISTINCT]
(column [{, columns}])| *
FROM table [ {, table}]
[ORDER BY column [ASC] | DESC
[ {, column [ASC] | DESC }]];
定義選擇標准
在我們目前所介紹的SELECT語句中,我們對結果表中的列作出了選擇但返回的是表中所有的行。讓我們看一下如何對SELECT語句進行限制使得它只返回希望得到的行:
SELECT columns FROM tables [WHERE predicates];
WHERE子句對條件進行了設置,只有滿足條件的行才被包括到結果表中。這些條件由斷言(predicate)進行指定(斷言指出了關於某件事情的一種可能的事實)。如果該斷言對於某個給定的行成立,該行將被包括到結果表中,否則該行被忽略。在SQL語句中斷言通常通過比較來表示。例如,假如你需要查詢所有姓為Jones的職員,則可以使用以下SELECT語句:
SELECT * FROM EMPLOYEES
WHERE LAST_NAME = 'Jones';
LAST_NAME = 'Jones'部分就是斷言。在執行該語句時,SQL將每一行的LAST_NAME列與「Jones」進行比較。如果某一職員的姓為「Jones」,即斷言成立,該職員的信息將被包括到結果表中(見表6)。
使用最多的六種比較
我們上例中的斷言包括一種基於「等值」的比較(LAST_NAME = 'Jones'),但是SQL斷言還可以包含其他幾種類型的比較。其中最常用的為:
等於 =
不等於 <>
小於 <
大於 >
小於或等於 <=
大於或等於 >=
下面給出了不是基於等值比較的一個例子:
SELECT * FROM EMPLOYEES
WHERE SALARY > 50000;
這一查詢將返回年薪高於$50,000.00的職員(參見表7)。
邏輯連接符
有時我們需要定義一條不止一種斷言的SELECT語句。舉例來說,如果你僅僅想查看Davy Jones的信息的話,表6中的結果將是不正確的。為了進一步定義一個WHERE子句,用戶可以使用邏輯連接符AND,OR和NOT。為了只得到職員Davy Jones的記錄,用戶可以輸入如下語句:
SELECT * FROM EMPLOYEES
WHERE LAST_NAME = 'Jones' AND FIRST_NAME = 'Davy';
在本例中,我們通過邏輯連接符AND將兩個斷言連接起來。只有兩個斷言都滿足時整個表達式才會滿足。如果用戶需要定義一個SELECT語句來使得當其中任何一項成立就滿足條件時,可以使用OR連接符:
SELECT * FROM EMPLOYEES
WHERE LAST_NAME = 'Jones' OR LAST_NAME = 'Smith';
有時定義一個斷言的最好方法是通過相反的描述來說明。如果你想要查看除了Boston辦事處的職員以外的其他所有職員的信息時,你可以進行如下的查詢:
SELECT * FROM EMPLOYEES
WHERE NOT(BRANCH_OFFICE = 'Boston');
關鍵字NOT後面跟著用圓括弧括起來的比較表達式。其結果是對結果取否定。如果某一職員所在部門的辦事處在Boston,括弧內的表達式返回true,但是NOT操作符將該值取反,所以該行將不被選中。
斷言可以與其他的斷言嵌套使用。為了保證它們以正確的順序進行求值,可以用括弧將它們括起來:
SELECT * FROM EMPLOYEES
WHERE (LAST_NAME = 'Jones'
AND FIRST_NAME = 'Indiana')
OR (LAST_NAME = 'Smith'
AND FIRST_NAME = 'Bessie');
SQL沿用數學上標準的表達式求值的約定—圓括弧內的表達式將最先進行求值,其他表達式將從左到右進行求值。
以上對邏輯連接符進行了說明,在對下面的內容進行說明之前,我們再一次對SELECT語句的語法進行更新:
SELECT [DISTINCT]
(column [{, column } ] )| *
FROM table [ { , table} ]
[ORDER BY column [ASC] | [DESC
[{ , column [ASC] | [DESC } ] ]
WHERE predicate [ { logical-connector predicate } ];
NULL和三值邏輯
在SQL中NULL是一個復雜的話題,關於NULL的詳細描述更適合於在SQL的高級教程而不是現在的入門教程中進行介紹。但由於NULL需要進行特殊處理,並且你也很可能會遇到它,所以我們還是簡略地進行一下說明。
首先,在斷言中進行NULL判斷時需要特殊的語法。例如,如果用戶需要顯示所有年薪未知的職員的全部信息,用戶可以使用如下SELECT語句:
SELECT * FROM EMPLOYEES
WHERE SALARY IS NULL;
相反,如果用戶需要所有已知年薪數據的職員的信息,你可以使用以下語句:
SELECT * FROM EMPLOYEES
WHERE SALARY IS NOT NULL;
請注意我們在列名之後使用了關鍵字IS NULL或IS NOT NULL,而不是標準的比較形式:COLUMN = NULL、COLUMN <> NULL或是邏輯操作符NOT(NULL)。
這種形式相當簡單。但當你不明確地測試NULL(而它們確實存在)時,事情會變得很混亂。
例如,回過頭來看我們圖1中的EM-PLOYEES表,可以看到Indiana Jones的工薪等級或年薪值都是未知的。這兩個列都包含NULL。可以想像運行如下的查詢:
SELECT * FROM EMPLOYEES
WHERE GRADE <= SALARY;
此時,Indiana Jones應該出現在結果表中。因為NULL都是相等的,所以可以想像它們是能夠通過GRADE小於等於SALARY的檢查的。這其實是一個毫無疑義的查詢,但是並沒有關系。SQL允許進行這樣的比較,只要兩個列都是數字類型的。然而,Indiana Jones並沒有出現在查詢的結果中,為什麼?
正如我們早先提到過的,NULL表示未知的值(而不是象某些人所想像的那樣表示一個為NULL的值)。對於SQL來說意味著這個值是未知的,而只要這個值為未知,就不能將其與其他值比較(即使其他值也是NULL)。所以SQL允許除了在true 和false之外還有第三種類型的真值,稱之為「非確定」(unknown)值。
如果比較的兩邊都是NULL,整個斷言就被認為是非確定的。將一個非確定斷言取反或使用AND或OR與其他斷言進行合並之後,其結果仍是非確定的。由於結果表中只包括斷言值為「真」的行,所以NULL不可能滿足該檢查。從而需要使用特殊的操作符IS NULL和IS NOT NULL。
UPDATE語句
UPDATE語句允許用戶在已知的表中對現有的行進行修改。
例如,我們剛剛發現Indiana Jones的等級為16,工資為$40,000.00,我們可以通過下面的SQL語句對資料庫進行更新(並清除那些煩人的NULL)。
UPDATE EMPLOYEES
SET GRADE = 16, SALARY = 40000
WHERE FIRST_NAME = 'Indiana'
AND LAST_NAME = 'Jones';
上面的例子說明了一個單行更新,但是UPDATE語句可以對多行進行操作。滿足WHERE條件的所有行都將被更新。如果,你想讓Boston辦事處中的所有職員搬到New York,你可以使用如下語句:
UPDATE EMPLOYEES
SET BRANCH_OFFICE = 'New York'
WHERE BRANCH_OFFICE = 'Boston';
如果忽略WHERE子句,表中所有行中的部門值都將被更新為'New York'。
UPDATE語句的語法流圖如下面所示:
UPDATE table
SET column = value [{, column = value}]
[ WHERE predicate [ { logical-connector predicate}]];
DELETE語句
DELETE語句用來刪除已知表中的行。如同UPDATE語句中一樣,所有滿足WHERE子句中條件的行都將被刪除。由於SQL中沒有UNDO語句或是「你確認刪除嗎?」之類的警告,在執行這條語句時千萬要小心。如果決定取消Los Angeles辦事處並解僱辦事處的所有職員,這一卑鄙的工作可以由以下這條語句來實現:
DELETE FROM EMPLOYEES
WHERE BRANCH_OFFICE = 'Los Angeles';
如同UPDATE語句中一樣,省略WHERE子句將使得操作施加到表中所有的行。
DELETE語句的語法流圖如下面所示:
DELETE FROM table
[WHERE predicate [ { logical-connector predicate} ] ];
現在我們完成了數據操作語言(DML)的主要語句的介紹。我們並沒有對SQL能完成的所有功能進行說明。SQL還提供了許多的功能,如求平均值、求和以及其他對表中數據的計算,此外SQL還能完成從多個表中進行查詢(多表查詢,或稱之為連接)的工作。這種語言還允許你使用GRANT和REVOKE命令控制使用者的數據訪問許可權
9. 如何在sql server中存儲圖片
1、首先可以存儲圖片鏈接,設置圖片鏈接欄位,如下圖所示。
10. SQL的簡單介紹(基本的sql語句)
SQL是StructuredQuevyLanguage(結構化查詢語言)的縮寫。SQL是專為資料庫而建立的操作命令集,是一種功能齊全的資料庫語言。在使用它時,只需要發出「做什麼」的命令,「怎麼做」是不用使用者考慮的。SQL功能強大、簡單易學、使用方便,已經成為了資料庫操作的基礎,並且現在幾乎所有的資料庫均支持SQL。
##1二、SQL資料庫數據體系結構
SQL資料庫的數據體系結構基本上是三級結構,但使用術語與傳統關系模型術語不同。在SQL中,關系模式(模式)稱為「基本表旅凱」(basetable);存儲模式(內模式)稱為「存儲文件」(storedfile);子模式(外模式)稱為「視圖」(view);元組稱為「行」(row);屬性稱為「列」(column)。名稱對稱如^00100009a^:
##1三、SQL語言的組成
在正式學習SQL語言之前,首先讓我們對SQL語言有一個基本認識,介紹一下SQL語言的組成:
1.一個SQL資料庫是表(Table)的集合,它由一個或多個SQL模式定義。
2.一個SQL表由行集構成,一行是列的序列(集合),每列與行對應一個數據項。
3.一個表或者是一個基本表或者是一個視圖。基本表是實際存儲在資料庫的表,而視圖是由若干基本表或其他視圖構成的表的定義。
4.一個基本表可以跨一個或多個存儲文件,一個存儲文件也可存放一個或多個基本表。每個存儲文件與外部存儲上一個物理文件對應。
5.用戶可以用SQL語句對視圖和基本表進行查詢等操作。在用戶角度來看,視圖和基本表是一樣的,沒有區別,都是關系(表格)。
6.SQL用戶可以是應用程序,也可以是終端用戶。SQL語句可嵌入在宿主語言的程序中使用,宿主語言有FORTRAN,COBOL,PASCAL,PL/I,C和Ada語言等。SQL用戶也能作為獨立的用戶介面,供交互環境下的終端用戶使用。
##1四、對資料庫進行操作
SQL包括了所有對資料庫的操作,主要是由4個部分組成:
1.數據定義:這一部分又稱為「SQLDDL」,定義資料庫的邏輯結構,包括定義資料庫、基本表、視圖和索引4部分。
2.數據操縱:這一部分又稱為「SQLDML」,其中包括數據查詢和數據更新兩大類操作,其中數據更絕豎新又包括插入、刪除和更新三種操作。
3.數據控制:對用戶訪問數據的控制有基本表和視圖的授權、完整性規則的描述,事務控制語句等。
4.嵌入式SQL語言的使用規定:規定SQL語句在宿主語言的程序中使用的規則。
下面我們將分別介紹:
##2(一)數拆宏喚據定義
SQL數據定義功能包括定義資料庫、基本表、索引和視圖。
首先,讓我們了解一下SQL所提供的基本數據類型:(如^00100009b^)
1.資料庫的建立與刪除
(1)建立資料庫:資料庫是一個包括了多個基本表的數據集,其語句格式為:
CREATEDATABASE<資料庫名<〔其它參數〕
其中,<資料庫名<在系統中必須是唯一的,不能重復,不然將導致數據存取失誤。〔其它參數〕因具體資料庫實現系統不同而異。
例:要建立項目管理資料庫(xmmanage),其語句應為:
CREATEDATABASExmmanage
(2)資料庫的刪除:將資料庫及其全部內容從系統中刪除。
其語句格式為:DROPDATABASE<資料庫名<
例:刪除項目管理資料庫(xmmanage),其語句應為:
DROPDATABASExmmanage
2.基本表的定義及變更
本身獨立存在的表稱為基本表,在SQL語言中一個關系唯一對應一個基本表。基本表的定義指建立基本關系模式,而變更則是指對資料庫中已存在的基本表進行刪除與修改。