电竞比分网-中国电竞赛事及体育赛事平台

分享

SQL數(shù)據(jù)庫面試題

 昵稱3363160 2010-09-15
  SQL數(shù)據(jù)庫面試題


1、SQL SREVER中,向一個表中插入了新數(shù)據(jù),如何快捷的得到自增量字段的當前值

這種情況其實我們經(jīng)常用到,比如我們新建了一個用戶,建立完用戶后我們希望馬上得到這個新用戶的ID,因為我們一般都是把這種用戶ID的字段設(shè)置成自增長類型的,乍看起來好像沒有要得到那個新ID很麻煩,其實sql server內(nèi)置了一些全局的變量,使我們很容易就得到那個新的自增字段的ID,就是使用@@IDENTITY。

      在一條 INSERT、SELECT INTO 或大容量復(fù)制語句完成后,@@IDENTITY 中包含語句生成的最后一個標識值。如果語句未影響任何包含標識列的表,則 @@IDENTITY 返回 NULL。如果插入了多個行,生成了多個標識值,則 @@IDENTITY 將返回最后生成的標識值。如果語句觸發(fā)了一個或多個觸發(fā)器,該觸發(fā)器又執(zhí)行了生成標識值的插入操作,那么,在語句執(zhí)行后立即調(diào)用 @@IDENTITY 將返回觸發(fā)器生成的最后一個標識值。

在具體應(yīng)用中可以這樣來寫SQL語句:

string strSql = "INSERT INTO [User]([Name],[LoginName],[Pwd],[RegTime],[IsSuper],[Remark])" +
                "VALUES(@Name,@LoginName,@Pwd,@RegTime,@IsSuper,@Remark);select @@IDENTITY ;";

執(zhí)行的時候直接用command.ExecuteScalar();就可以了,能直接返回該條記錄的UserID;

解答二:

經(jīng)過實驗,得如下結(jié)論:

select DISTINCT @@IDENTITY as iden from FaWen

解釋:上述語句對 SQL SERVER 的一個會話,也就是一條連接,返回該連接最后一條插入記錄得到的自增字段的值。

假設(shè)有3個程序,分別連接SQL SERVER,有三個連接。3個程序都向同一個表依順序插入數(shù)據(jù),得到的值分別是1、2、3,那么,只要3個程序?qū)QL的連接還保持著,第一個程序使用上述語句,將得到1,而不是3,第二個程序?qū)⒌玫?,也不是3。第三個程序得到3。

因此,用上述語句可以得到自己剛才插入記錄的自增字段的值,不怕其它程序的并發(fā)插入操作。

上述語句中,使用 DISTINCT  的原因是,雖然返回的值是當前連接插入操作得到的最大值,但返回的相同值的記錄有多條。條數(shù)等于當前多個連接一共插入的記錄數(shù)。

實驗方法:啟動三個 Query analyzer 查詢分析器,分別執(zhí)行插入操作后再做上述取自增字段值的操作

 
 
我利用  
  rs.addnew  
  增加一條記錄時,如何同時獲取自增1字段ID的當前值,而無須再進行一次查詢來獲?。∫驗槲伊⒓匆玫皆揑D值,如果在增加記錄完畢后再利用select   id   進行一次查詢無疑會使系統(tǒng)受限,有辦法嗎?
 
如果你能保證id=行數(shù)的話可以用  
  rs.moveend   '當指針在最后一條記錄時count是全部行數(shù)  
  rs.count
2、什么叫做SQL注入,如何防止?請舉例說明

SQL注入就是在正常的SQL執(zhí)行語句中惡意插入攻擊者想要運行的sql語句,比如,我們有一個方法是這么寫的:

public static bool Login(string loginName,string pwd)
        {
            string strSql = string.Format("select *  from [User] where LoginName = '{0}' and Pwd = '{1}' ",loginName,pwd);

        ...

          }

如果我傳給loginname的值是' or 1=1--,那么這個sql語句成了select *  from [User] where LoginName = '' or 1=1--',這樣不管我密碼輸入什么,肯定都是符合條件的。當然這只是最簡單的情況,如果我把loginname的值改成' or 1=1;delete from [user]--,那么后果不堪設(shè)想,如果我通過sql來執(zhí)行net use相關(guān)的命令,就可能在服務(wù)器上給自己加一個賬號,這樣就逐步可以控制整個數(shù)據(jù)庫所在的服務(wù)器。。。

這就是sql注入的通常方法和可能的損害。

要放置其實也很簡單,可以通過至少兩個方法來進行:

1.最根本的,不實用組合sql的方法,而是通過使用命令參數(shù)方式來執(zhí)行命令,比如我們把sql改成這種方式:

string strSql = "select * from [user] where LoginName =@LoginName and Pwd =@Pwd ";

,然后通過sqlcommand來執(zhí)行它,就可以從根本上解決這個問題。

2.控制參數(shù)的長度。因為要想進行sql注入的話,需要一定長度的字符串才能執(zhí)行,如果我們規(guī)定LoginName 的長度最長不超過8個,一般不會造成損害,當然這個只是在特殊的情況下才使用,比如有些情況可能不能使用命令參數(shù)方式。

點評:

sql注入是我們編程時必須考慮的問題,特別是BS的程序,更是要嚴格檢查是否有sql注入的漏洞。最關(guān)鍵的一點是,你要明白怎么解決這個問題,一般面試人員會希望你提高使用參數(shù)方式來防止注入。

3、游標的作用?如何知道游標已經(jīng)到了最后?

關(guān)系數(shù)據(jù)庫中的操作會對整個行集起作用。由 SELECT 語句返回的行集包括滿足該語句的 WHERE 子句中條件的所有行。這種由語句返回的完整行集稱為結(jié)果集。應(yīng)用程序,特別是交互式聯(lián)機應(yīng)用程序,并不總能將整個結(jié)果集作為一個單元來有效地處理。這些應(yīng)用程序需要一種機制以便每次處理一行或一部分行。游標就是提供這種機制的對結(jié)果集的一種擴展。

游標的特點是:

允許定位在結(jié)果集的特定行。
從結(jié)果集的當前位置檢索一行或一部分行。
支持對結(jié)果集中當前位置的行進行數(shù)據(jù)修改。
為由其他用戶對顯示在結(jié)果集中的數(shù)據(jù)庫數(shù)據(jù)所做的更改提供不同級別的可見性支持。
提供腳本、存儲過程和觸發(fā)器中用于訪問結(jié)果集中的數(shù)據(jù)的 Transact-SQL 語句
在從游標中提取信息后,可以通過判斷@@FETCH_STATUS 的值來判斷是否到了最后。當@@FETCH_STATUS為0的時候,說明提取是成功的,否則就可以認為到了最后。

點評:

游標是進行數(shù)據(jù)庫操作的一個重要概念,但是在現(xiàn)代的軟件開發(fā)中應(yīng)用的不是很多,只有在一些特殊的存儲過程中才會應(yīng)用。但是,畢竟這是一個很重要,也是我們必須掌握的概念,最好能理解它的原理和用法。

4、SQL Server的兩種索引是何形式?索引的作用?索引的優(yōu)缺點?

sql server的索引分為聚集索引和非聚集索引,下面分別說明:
聚集索引
聚集索引根據(jù)數(shù)據(jù)行的鍵值在表或視圖中排序和存儲這些數(shù)據(jù)行。索引定義中包含聚集索引列。每個表只能有一個聚集索引,因為數(shù)據(jù)行本身只能按一個順序排序。
只有當表包含聚集索引時,表中的數(shù)據(jù)行才按排序順序存儲。如果表具有聚集索引,則該表稱為聚集表。如果表沒有聚集索引,則其數(shù)據(jù)行存儲在一個稱為堆的無序結(jié)構(gòu)中。

非聚集索引
非聚集索引具有獨立于數(shù)據(jù)行的結(jié)構(gòu)。非聚集索引包含非聚集索引鍵值,并且每個鍵值項都有指向包含該鍵值的數(shù)據(jù)行的指針。
從非聚集索引中的索引行指向數(shù)據(jù)行的指針稱為行定位器。行定位器的結(jié)構(gòu)取決于數(shù)據(jù)頁是存儲在堆中還是聚集表中。對于堆,行定位器是指向行的指針。對于聚集表,行定位器是聚集索引鍵。


索引的作用主要是為了在查詢時提高查詢的效率,并且盡量減小更新時的開銷。

優(yōu)點:

設(shè)計良好的索引查詢效率可以得到極大的提高,某些情況下甚至可以提高幾百上千倍。

缺點:

需要占用額外的空間和資源。在更新時耗費的時間更大,因為對數(shù)據(jù)的更新很有可能會導(dǎo)致索引的更新,這樣就會導(dǎo)致增加系統(tǒng)開銷。

點評:

在所有的進行系統(tǒng)優(yōu)化的選擇中,索引都是第一位的,一個設(shè)計良好的數(shù)據(jù)庫肯定需要高超的索引設(shè)計技巧,在這方面效率提高不是一倍兩倍的問題,而是可能會有質(zhì)的飛躍,對索引優(yōu)化的重要性,在一個大型項目里,怎么說都不為過。但是,索引優(yōu)化又是比較困難的,哪些列需要加入索引,列的順序怎樣,哪個索引需要設(shè)置為聚集索引等等,都是我們必須要考慮的問題。

5、事務(wù)是什么?

事務(wù)是單個的工作單元。如果某一事務(wù)成功,則在該事務(wù)中進行的所有數(shù)據(jù)修改均會提交,成為數(shù)據(jù)庫中的永久組成部分。

如果事務(wù)遇到錯誤且必須取消或回滾,則所有數(shù)據(jù)修改均被清除。

也就是說,事務(wù)是由一系列的“原子”操作組成的,這些原子操作必須全部完成,否則所有的動作都會被取消并恢復(fù)到初始狀態(tài)。

開始事務(wù)使用BEGIN TRANSACTION 語句顯,以 COMMIT 或 ROLLBACK 語句結(jié)束。

以上是針對數(shù)據(jù)庫來說的。

但是,事務(wù)不僅僅限于數(shù)據(jù)庫,數(shù)據(jù)庫以外的動作也可以被組合進事務(wù)中,一般稱為“企業(yè)級事務(wù)”。舉一個例子:我們有這兩個操作必須都完成,即在向數(shù)據(jù)庫插入一條記錄后必須在硬盤的某個文件夾內(nèi)創(chuàng)建一個文件,這個就是一個企業(yè)級事務(wù),它超出了簡單的數(shù)據(jù)庫事務(wù)的范疇。我們可以通過編程來實現(xiàn)企業(yè)級事務(wù)。

點評:

事務(wù)是數(shù)據(jù)庫開發(fā)中一個非常重要的概念,它對與保證數(shù)據(jù)庫的完整性和一致性非常重要。對于事務(wù)的的C#代碼實現(xiàn)更是務(wù)必要熟練掌握。

6、存儲過程和函數(shù)的區(qū)別

存儲過程,功能強大,可以執(zhí)行包括修改表等一系列數(shù)據(jù)庫操作,也可以創(chuàng)建為 SQL Server 啟動時自動運行的存儲過程。
自定義函數(shù),用戶定義函數(shù)不能用于執(zhí)行一組修改全局數(shù)據(jù)庫狀態(tài)的操作。
 

存儲過程,可以使用非確定函數(shù)。
自定義函數(shù),不允許在用戶定義函數(shù)主體中內(nèi)置非確定函數(shù)。
 

存儲過程,可返回記錄集。
自定義函數(shù),可以返回表變量,也可以有任意個輸出參數(shù),
 

存儲過程,其返回值不能被直接引用,必須單獨調(diào)用
自定義函數(shù),其返回值可以被直接引用,也就是可以直接 select * from 函數(shù)


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多