SQL常見筆試面試題


sql理論題

1.觸發器的作用?

 

  答:觸發器是一中特殊的存儲過程,主要是通過事件來觸發而被執行的。它可以強化約束,來維護數據的完整性和一致性,可以跟蹤數據庫內的操作從而不允許未經許可的更新和變化。可以聯級運算。如,某表上的觸發器上包含對另一個表的數據操作,而該操作又會導致該表觸發器被觸發。

 

2。什么是存儲過程?用什么來調用?

 

答:存儲過程是一個預編譯的SQL語句,優點是允許模塊化的設計,就是說只需創建一次,以后在該程序中就可以調用多次。如果某次操作需要執行多次SQL,使用存儲過程比單純SQL語句執行要快。可以用一個命令對象來調用存儲過程。

 

3。索引的作用?和它的優點缺點是什么?

答:索引就一種特殊的查詢表,數據庫的搜索引擎可以利用它加速對數據的檢索。它很類似與現實生活中書的目錄,不需要查詢整本書內容就可以找到想要的數據。索引可以是唯一的,創建索引允許指定單個列或者是多個列。缺點是它減慢了數據錄入的速度,同時也增加了數據庫的尺寸大小。

 

3。什么是內存泄漏?

答:一般我們所說的內存泄漏指的是堆內存的泄漏。堆內存是程序從堆中為其分配的,大小任意的,使用完后要顯示釋放內存。當應用程序用關鍵字new等創建對象時,就從堆中為它分配一塊內存,使用完后程序調用free或者delete釋放該內存,否則就說該內存就不能被使用,我們就說該內存被泄漏了。

 

4。維護數據庫的完整性和一致性,你喜歡用觸發器還是自寫業務邏輯?為什么?

 

答:我是這樣做的,盡可能使用約束,如check,主鍵,外鍵,非空字段等來約束,這樣做效率最高,也最方便。其次是使用觸發器,這種方法可以保證,無論什么業務系統訪問數據庫都可以保證數據的完整新和一致性。最后考慮的是自寫業務邏輯,但這樣做麻煩,編程復雜,效率低下。

 

5。什么是事務?什么是鎖?

答:事務就是被綁定在一起作為一個邏輯工作單元的SQL語句分組,如果任何一個語句操作失敗那么整個操作就被失敗,以后操作就會回滾到操作前狀態,或者是上有個節點。為了確保要么執行,要么不執行,就可以使用事務。要將有組語句作為事務考慮,就需要通過ACID測試,即原子性,一致性,隔離性和持久性。

 

  鎖:在所以的DBMS中,鎖是實現事務的關鍵,鎖可以保證事務的完整性和並發性。與現實生活中鎖一樣,它可以使某些數據的擁有者,在某段時間內不能使用某些數據或數據結構。當然鎖還分級別的。

 

6。什么叫視圖?游標是什么?

答:視圖是一種虛擬的表,具有和物理表相同的功能。可以對視圖進行增,改,查,操作,試圖通常是有一個表或者多個表的行或列的子集。對視圖的修改不影響基本表。它使得我們獲取數據更容易,相比多表查詢。

 

  游標:是對查詢出來的結果集作為一個單元來有效的處理。游標可以定在該單元中的特定行,從結果集的當前行檢索一行或多行。可以對結果集當前行做修改。一般不使用游標,但是需要逐條處理數據的時候,游標顯得十分重要。

 

7。為管理業務培訓信息,建立3個表:

     S(S#,SN,SD,SA)S#,SN,SD,SA分別代表學號,學員姓名,所屬單位,學員年齡

     C(C#,CN)C#,CN分別代表課程編號,課程名稱

     SC(S#,C#,G) S#,C#,G分別代表學號,所選的課程編號,學習成績

 (1)使用標准SQL嵌套語句查詢選修課程名稱為’稅收基礎’的學員學號和姓名?

      答案:select s# ,sn from s where S# in(select S# from c,sc where c.c#=sc.c# and  cn=’稅收基礎’)

  (2) 使用標准SQL嵌套語句查詢選修課程編號為’C2’的學員姓名和所屬單位?

答:select sn,sd from s,sc where s.s#=sc.s# and sc.c#=’c2’

 (3) 使用標准SQL嵌套語句查詢不選修課程編號為’C5’的學員姓名和所屬單位?

答:select sn,sd from s where s# not in(select s# from sc where c#=’c5’)

 (3)列出有二門以上(含兩門)不及格課程的學生姓名及其平均成績

答:select s.sn,avg(sc.g) from s,sc where s.s#=sc.s# group by s.sn having count(case when s.g<60 then 1 end)>=2;

 (4)查詢選修了課程的學員人數

答:select 學員人數=count(distinct s#) from sc

 

(5) 查詢選修課程超過5門的學員學號和所屬單位?

答:select sn,sd from s where s# in(select s# from sc group by s# having count(distinct  c#)>5)

 

是查詢A(ID,Name)表中第31至40條記錄,ID作為主鍵可能是不是連續增長的列,完整的查詢語句如下:

 

select  top 10 * from A where ID >(select max(ID) from (select  top 30 ID from A order by A

) T) order by A

 

要求是查詢表A中存在ID重復三次以上的記錄,完整的查詢語句如下:

select * from(select count(ID) as count from table group by ID)T where T.count>3

 

create table testtable1

(

 id int IDENTITY,

 department varchar(12)

)

 

select * from testtable1

insert into testtable1 values('設計')

insert into testtable1 values('市場')

insert into testtable1 values('售后')

/*

結果

id  department

1   設計

2   市場

3   售后

*/

create table testtable2

(

 id int IDENTITY,

 dptID int,

 name varchar(12)

)

insert into testtable2 values(1,'張三')

insert into testtable2 values(1,'李四')

insert into testtable2 values(2,'王五')

insert into testtable2 values(3,'彭六')

insert into testtable2 values(4,'陳七')

/*

用一條SQL語句,怎么顯示如下結果

id  dptID  department  name

1   1      設計        張三

2   1      設計        李四

3   2      市場        王五

4   3      售后        彭六

5   4      黑人        陳七

*/

 

答案是:

 

SELECT testtable2.*  , ISNULL(department,'黑人')

FROM testtable1 right join testtable2 on testtable2.dptID = testtable1.ID

 

 

 

在面試應聘的SQL Server數據庫開發人員時,我運用了一套標准的基准技術問題。下面這些問題是我覺得能夠真正有助於淘汰不合格應聘者的問題。它們按照從易到難的順序排列。當你問到關於主鍵和外鍵的問題時,后面的問題都十分有難度,因為答案可能會更難解釋和說明,尤其是在面試的情形下。

 

你能向我簡要敘述一下SQL Server 2000中使用的一些數據庫對象嗎?

 

你希望聽到的答案包括這樣一些對象:表格、視圖、用戶定義的函數,以及存儲過程;如果他們還能夠提到像觸發器這樣的對象就更好了。如果應聘者不能回答這個基本的問題,那么這不是一個好兆頭。

 

NULL是什么意思?

NULL(空)這個值是數據庫世界里一個非常難纏的東西,所以有不少應聘者會在這個問題上跌跟頭您也不要覺得意外。 NULL這個值表示UNKNOWN(未知):它不表示“”(空字符串)。假設您的SQL Server數據庫里有ANSI_NULLS,當然在默認情況下會有,對NULL這個值的任何比較都會生產一個NULL值。您不能把任何值與一個 UNKNOWN值進行比較,並在邏輯上希望獲得一個答案。您必須使用IS NULL操作符。

 

什么是索引?SQL Server 2000里有什么類型的索引?

 

任何有經驗的數據庫開發人員都應該能夠很輕易地回答這個問題。一些經驗不太多的開發人員能夠回答這個問題,但是有些地方會說不清楚。簡單地說,索引是一個數據結構,用來快速訪問數據庫表格或者視圖里的數據。在SQL Server里,它們有兩種形式:聚集索引和非聚集索引。聚集索引在索引的葉級保存數據。這意味着不論聚集索引里有表格的哪個(或哪些)字段,這些字段都會按順序被保存在表格。由於存在這種排序,所以每個表格只會有一個聚集索引。非聚集索引在索引的葉級有一個行標識符。這個行標識符是一個指向磁盤上數據的指針。它允許每個表格有多個非聚集索引。

 

什么是主鍵?什么是外鍵?

 

主鍵是表格里的(一個或多個)字段,只用來定義表格里的行;主鍵里的值總是唯一的。外鍵是一個用來建立兩個表格之間關系的約束。這種關系一般都涉及一個表格里的主鍵字段與另外一個表格(盡管可能是同一個表格)里的一系列相連的字段。那么這些相連的字段就是外鍵。

 

什么是觸發器?SQL Server 2000有什么不同類型的觸發器?

 讓未來的數據庫開發人員知道可用的觸發器類型以及如何實現它們是非常有益的。觸發器是一種專用類型的存儲過程,它被捆綁到SQL Server 2000的表格或者視圖上。在SQL Server 2000里,有INSTEAD-OF和AFTER兩種觸發器。INSTEAD-OF觸發器是替代數據操控語言(Data Manipulation

Language,DML)語句對表格執行語句的存儲過程。例如,如果我有一個用於TableA的INSTEAD-OF-UPDATE

觸發器,同時對這個表格執行一個更新語句,那么INSTEAD-OF-UPDATE觸發器里的代碼會執行,而不是我執行的更新語句則不會執行操作。

 

AFTER觸發器要在DML語句在數據庫里使用之后才執行。這些類型的觸發器對於監視發生在數據庫表格里的數據變化十分好用。

 

您如何確一個帶有名為Fld1字段的TableB表格里只具有Fld1字段里的那些值,而這些值同時在名為TableA的表格的Fld1字段里?

 

這個與關系相關的問題有兩個可能的答案。第一個答案(而且是您希望聽到的答案)是使用外鍵限制。外鍵限制用來維護引用的完整性。它被用來確保表格里的字段只保存有已經在不同的(或者相同的)表格里的另一個字段里定義了的值。這個字段就是候選鍵(通常是另外一個表格的主鍵)。

 

另外一種答案是觸發器。觸發器可以被用來保證以另外一種方式實現與限制相同的作用,但是它非常難設置與維護,而且性能一般都很糟糕。由於這個原因,微軟建議開發人員使用外鍵限制而不是觸發器來維護引用的完整性。

 

對一個投入使用的在線事務處理表格有過多索引需要有什么樣的性能考慮?

 

你正在尋找進行與數據操控有關的應聘人員。對一個表格的索引越多,數據庫引擎用來更新、插入或者刪除數據所需要的時間就越多,因為在數據操控發生的時候索引也必須要維護。

 

你可以用什么來確保表格里的字段只接受特定范圍里的值?

 

這個問題可以用多種方式來回答,但是只有一個答案是“好”答案。您希望聽到的回答是Check限制,它在數據庫表格里被定義,用來限制輸入該列的值。

 

觸發器也可以被用來限制數據庫表格里的字段能夠接受的值,但是這種辦法要求觸發器在表格里被定義,這可能會在某些情況下影響到性能。因此,微軟建議使用Check限制而不是其他的方式來限制域的完整性。

 

如果應聘者能夠正確地回答這個問題,那么他的機會就非常大了,因為這表明他們具有使用存儲過程的經驗。

 

返回參數總是由存儲過程返回,它用來表示存儲過程是成功還是失敗。返回參數總是INT數據類型。

 

OUTPUT參數明確要求由開發人員來指定,它可以返回其他類型的數據,例如字符型和數值型的值。(可以用作輸出參數的數據類型是有一些限制的。)您可以在一個存儲過程里使用多個OUTPUT參數,而您只能夠使用一個返回參數。

 

什么是相關子查詢?如何使用這些查詢?

 

經驗更加豐富的開發人員將能夠准確地描述這種類型的查詢。相關子查詢是一種包含子查詢的特殊類型的查詢。查詢里包含的子查詢會真正請求外部查詢的值,從而形成一個類似於循環的狀況。

 

什么是SQL注入式攻擊?

所謂SQL注入式攻擊,就是攻擊者把SQL命令插入到Web表單的輸入域或頁面請求的查詢字符串,欺騙服務器執行惡意的SQL命令。在某些表單中,用戶輸入的內容直接用來構造(或者影響)動態SQL命令,或作為存儲過程的輸入參數,這類表單特別容易受到SQL注入式攻擊。常見的SQL注入式攻擊過程類如:

⑴ 某個ASP.NET Web應用有一個登錄頁面,這個登錄頁面控制着用戶是否有權訪問應用,它要求用戶輸入一個名稱和密碼。

⑵ 登錄頁面中輸入的內容將直接用來構造動態的SQL命令,或者直接用作存儲過程的參數。下面是ASP.NET應用構造查詢的一個例子:

System.Text.StringBuilder query = new System.Text.StringBuilder(

   "SELECT * from Users WHERE login = '")

   .Append(txtLogin.Text).Append("' AND password='")

   .Append(txtPassword.Text).Append("'");

 

⑶ 攻擊者在用戶名字和密碼輸入框中輸入"'或'1'='1"之類的內容。

⑷ 用戶輸入的內容提交給服務器之后,服務器運行上面的ASP.NET代碼構造出查詢用戶的SQL命令,但由於攻擊者輸入的內容非常特殊,所以最后得到的SQL命令變成:SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'。

⑸ 服務器執行查詢或存儲過程,將用戶輸入的身份信息和服務器中保存的身份信息進行對比。

⑹ 由於SQL命令實際上已被注入式攻擊修改,已經不能真正驗證用戶身份,所以系統會錯誤地授權給攻擊者。

如果攻擊者知道應用會將表單中輸入的內容直接用於驗證身份的查詢,他就會嘗試輸入某些特殊的SQL字符串篡改查詢改變其原來的功能,欺騙系統授予訪問權限。

系統環境不同,攻擊者可能造成的損害也不同,這主要由應用訪問數據庫的安全權限決定。如果用戶的帳戶具有管理員或其他比較高級的權限,攻擊者就可能對數據庫的表執行各種他想要做的操作,包括添加、刪除或更新數據,甚至可能直接刪除表

如何防范SQL注入式攻擊?

好在要防止ASP.NET應用被SQL注入式攻擊闖入並不是一件特別困難的事情,只要在利用表單輸入的內容構造SQL命令之前,把所有輸入內容過濾一番就可以了。過濾輸入內容可以按多種方式進行。

⑴ 對於動態構造SQL查詢的場合,可以使用下面的技術:

第一:替換單引號,即把所有單獨出現的單引號改成兩個單引號,防止攻擊者修改SQL命令的含義。再來看前面的例子,"SELECT * from Users WHERE login = ''' or ''1''=''1' AND password = ''' or ''1''=''1'"顯然會得到與"SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'"不同的結果。

第二:刪除用戶輸入內容中的所有連字符,防止攻擊者構造出類如"SELECT * from Users WHERE login = 'mas' -- AND password =''"之類的查詢,因為這類查詢的后半部分已經被注釋掉,不再有效,攻擊者只要知道一個合法的用戶登錄名稱,根本不需要知道用戶的密碼就可以順利獲得訪問權限。

第三:對於用來執行查詢的數據庫帳戶,限制其權限。用不同的用戶帳戶執行查詢、插入、更新、刪除操作。由於隔離了不同帳戶可執行的操作,因而也就防止了原本用於執行SELECT命令的地方卻被用於執行INSERT、UPDATE或DELETE命令。

⑵ 用存儲過程來執行所有的查詢。SQL參數的傳遞方式將防止攻擊者利用單引號和連字符實施攻擊。此外,它還使得數據庫權限可以限制到只允許特定的存儲過程執行,所有的用戶輸入必須遵從被調用的存儲過程的安全上下文,這樣就很難再發生注入式攻擊了。

⑶ 限制表單或查詢字符串輸入的長度。如果用戶的登錄名字最多只有10個字符,那么不要認可表單中輸入的10個以上的字符,這將大大增加攻擊者在SQL命令中插入有害代碼的難度。

⑷ 檢查用戶輸入的合法性,確信輸入的內容只包含合法的數據。數據檢查應當在客戶端和服務器端都執行——之所以要執行服務器端驗證,是為了彌補客戶端驗證機制脆弱的安全性。

在客戶端,攻擊者完全有可能獲得網頁的源代碼,修改驗證合法性的腳本(或者直接刪除腳本),然后將非法內容通過修改后的表單提交給服務器。因此,要保證驗證操作確實已經執行,唯一的辦法就是在服務器端也執行驗證。你可以使用許多內建的驗證對象,例如 RegularExpressionValidator,它們能夠自動生成驗證用的客戶端腳本,當然你也可以插入服務器端的方法調用。如果找不到現成的驗證對象,你可以通過CustomValidator自己創建一個。

⑸ 將用戶登錄名稱、密碼等數據加密保存。加密用戶輸入的數據,然后再將它與數據庫中保存的數據比較,這相當於對用戶輸入的數據進行了"消毒"處理,用戶輸入的數據不再對數據庫有任何特殊的意義,從而也就防止了攻擊者注入SQL命令。 System.Web.Security.FormsAuthentication類有一個 HashPasswordForStoringInConfigFile,非常適合於對輸入數據進行消毒處理。

⑹ 檢查提取數據的查詢所返回的記錄數量。如果程序只要求返回一個記錄,但實際返回的記錄卻超過一行,那就當作出錯處理

 

 

Sql常見題目

為管理崗位業務培訓信息,建立3個表:

S (S#,SN,SD,SA) S#,SN,SD,SA 分別代表學號、學員姓名、所屬單位、學員年齡

C (C#,CN ) C#,CN 分別代表課程編號、課程名稱

SC ( S#,C#,G ) S#,C#,G 分別代表學號、所選修的課程編號、學習成績

1. 使用標准SQL嵌套語句查詢選修課程名稱為’稅收基礎’的學員學號和姓名

--實現代碼:

Select SN,SD FROM S Where [S#] IN( Select [S#] FROM C,SC Where C.[C#]=SC.[C#] AND CN=N'稅收基礎')

2. 使用標准SQL嵌套語句查詢選修課程編號為’C2’的學員姓名和所屬單位

--實現代碼:

Select S.SN,S.SD FROM S,SC Where S.[S#]=SC.[S#] AND SC.[C#]='C2'

3. 使用標准SQL嵌套語句查詢不選修課程編號為’C5’的學員姓名和所屬單位

--實現代碼:

Select SN,SD FROM S Where [S#] NOT IN( Select [S#] FROM SC Where [C#]='C5')

4. 使用標准SQL嵌套語句查詢選修全部課程的學員姓名和所屬單位

--實現代碼:

Select SN,SD FROM S Where [S#] IN( Select [S#] FROM SC RIGHT JOIN C ON SC.[C#]=C.[C#] GROUP BY [S#] HAVING COUNT(*)=COUNT([S#]))

5. 查詢選修了課程的學員人數

--實現代碼:

Select 學員人數=COUNT(DISTINCT [S#]) FROM SC

6. 查詢選修課程超過5門的學員學號和所屬單位

--實現代碼:

Select SN,SD FROM S Where [S#] IN( Select [S#] FROM SC GROUP BY [S#] HAVING COUNT(DISTINCT [C#])>5)

題目2:

問題描述:

S (SNO,SNAME) 學生關系。SNO 為學號,SNAME 為姓名

C (CNO,CNAME,CTEACHER) 課程關系。CNO 為課程號,CNAME 為課程名,CTEACHER 為任課教師

SC(SNO,CNO,SCGRADE) 選課關系。SCGRADE 為成績

1. 找出沒有選修過“李明”老師講授課程的所有學生姓名

--實現代碼:

Select SNAME FROM S Where NOT EXISTS( Select * FROM SC,C Where SC.CNO=C.CNO AND CNAME='李明' AND SC.SNO=S.SNO)

2. 列出有二門以上(含兩門)不及格課程的學生姓名及其平均成績

--實現代碼:

Select S.SNO,S.SNAME,AVG_SCGRADE=AVG(SC.SCGRADE) FROM S,SC,( Select SNO FROM SC Where SCGRADE<60 GROUP BY SNO HAVING COUNT(DISTINCT CNO)>=2 )A Where S.SNO=A.SNO AND SC.SNO=A.SNO GROUP BY S.SNO,S.SNAME

3. 列出既學過“1”號課程,又學過“2”號課程的所有學生姓名

--實現代碼:

Select S.SNO,S.SNAME FROM S,( Select SC.SNO FROM SC,C Where SC.CNO=C.CNO AND C.CNAME IN('1','2') GROUP BY SNO HAVING COUNT(DISTINCT CNO)=2 )SC Where S.SNO=SC.SNO

4. 列出“1”號課成績比“2”號同學該門課成績高的所有學生的學號

--實現代碼:

Select S.SNO,S.SNAME FROM S,( Select SC1.SNO FROM SC SC1,C C1,SC SC2,C C2 Where SC1.CNO=C1.CNO AND C1.NAME='1' AND SC2.CNO=C2.CNO AND C2.NAME='2' AND SC1.SCGRADE>SC2.SCGRADE )SC Where S.SNO=SC.SNO

5. 列出“1”號課成績比“2”號課成績高的所有學生的學號及其“1”號課和“2”號課的成績

--實現代碼:

Select S.SNO,S.SNAME,SC.[1號課成績],SC.[2號課成績] FROM S,( Select SC1.SNO,[1號課成績]=SC1.SCGRADE,[2號課成績]=SC2.SCGRADE FROM SC SC1,C C1,SC SC2,C C2 Where SC1.CNO=C1.CNO AND C1.NAME='1' AND SC2.CNO=C2.CNO AND C2.NAME='2' AND SC1.SCGRADE>SC2.SCGRADE )SC Where S.SNO=SC.SNO

 

 

求其中同一個號碼的兩次通話之間間隔大於10秒的通話記錄ID

例如:6,7,8,9,10條記錄均符合

ID 主叫號碼 被叫號碼      通話起始時間            通話結束時間            通話時長

1  98290000 0215466546656 2007-02-01 09:49:53.000 2007-02-01 09:50:16.000 23

2  98290000 021546654666  2007-02-01 09:50:29.000 2007-02-01 09:50:41.000 12

3  98290000 021546654666  2007-02-01 09:50:58.000 2007-02-01 09:51:12.000 14

4  68290900 0755133329866 2007-02-01 10:04:31.000 2007-02-01 10:07:13.000 162

5  78290000 0755255708638 2007-02-01 10:48:26.000 2007-02-01 10:49:23.000 57

6  78290000 0755821119109 2007-02-01 10:49:39.000 2007-02-01 10:52:55.000 196

7  78290000 035730928370  2007-02-01 11:30:45.000 2007-02-01 11:31:58.000 73

8  78290000 0871138889904 2007-02-01 11:33:47.000 2007-02-01 11:35:00.000 73

9  68290000 035730928379  2007-02-01 11:52:20.000 2007-02-01 11:54:56.000 156

10 68290000 0298521811199 2007-02-01 12:44:45.000 2007-02-01 12:45:04.000 19

 

答案:

SELECT DISTINCT a.* FROM dbo.hc a left join dbo.hc b

ON a.主叫號碼=b.主叫號碼

WHERE a.id<>b.id AND (DATEDIFF(second,a.通話起始時間,b.通話結束時間)>10 AND

DATEDIFF(second,b.通話起始時間,a.通話結束時間)>10)

 

 

Sql Server關於按周統計的問題

統計Sql Server里一個銷售明細表里某個時間段的銷售額,而且要按周進行比較,以下是該語句的寫法:

 

select sum(銷售金額), datename(week, 銷售日期-1) from sales where 銷售日期 betwee begindate and enddate group by datename(week, 銷售日期-1)

 

注意:這里之所以要把銷售日期-1是因為sql server默認的一周的第一天是星期天,而我們習慣的統計是以星期一到星期天計算的,所以減一。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM