SQLServer数据库⾯试题
SQL数据库⾯试题
1、SQL SREVER中,向⼀个表中插⼊了新数据,如何快捷的得到⾃增量字段的当前值
这种情况其实我们经常⽤到,⽐如我们新建了⼀个⽤户,建⽴完⽤户后我们希望马上得到这个新⽤户的ID,因为我们⼀般都是把这种⽤户ID 的字段设置成⾃增长类型的,乍看起来好像没有要得到那个新ID很⿇烦,其实sql server内置了⼀些全局的变量,使我们很容易就得到那个新的⾃增字段的ID,就是使⽤@@IDENTITY。
在⼀条 INSERT、SELECT INTO 或⼤容量复制语句完成后,@@IDENTITY 中包含语句⽣成的最后⼀个标识值。如果语句未影响任何包含标识列的表,则 @@IDENTITY 返回 NULL。如果插⼊了多个⾏,⽣成了多个标识值,则 @@IDENTITY 将返回最后⽣成的标识值。如果语句触发了⼀个或多个触发器,该触发器⼜执⾏了⽣成标识值的插⼊操作,那么,在语句执⾏后⽴即调⽤ @@IDENTITY 将返回触发器⽣成的最后⼀个标识值。
在具体应⽤中可以这样来写SQL语句:
string strSql = "INSERT INTO [User]([Name],[LoginName],[Pwd],[RegTime],[IsSuper],[Remark])" +
sql软件长什么样"VALUES(@Name,@LoginName,@Pwd,@RegTime,@IsSuper,@Remark);select @@IDENTITY ;";
执⾏的时候直接⽤command.ExecuteScalar();就可以了,能直接返回该条记录的UserID;
解答⼆:
经过实验,得如下结论:
select DISTINCT @@IDENTITY as iden from FaWen
解释:上述语句对 SQL SERVER 的⼀个会话,也就是⼀条连接,返回该连接最后⼀条插⼊记录得到的⾃增字段的值。
假设有3个程序,分别连接SQL SERVER,有三个连接。3个程序都向同⼀个表依顺序插⼊数据,得到的值分别是1、2、3,那么,只要3个程序对SQL的连接还保持着,第⼀个程序使⽤上述语句,将得到1,⽽不是3,第⼆个程序将得到2,也不是3。第三个程序得到3。
因此,⽤上述语句可以得到⾃⼰刚才插⼊记录的⾃增字段的值,不怕其它程序的并发插⼊操作。
上述语句中,使⽤ DISTINCT  的原因是,虽然返回的值是当前连接插⼊操作得到的最⼤值,但返回的相同值的记录有多条。条数等于当前多个连接⼀共插⼊的记录数。
实验⽅法:启动三个 Query analyzer 查询分析器,分别执⾏插⼊操作后再做上述取⾃增字段值的操作
我利⽤
rs.addnew
增加⼀条记录时,如何同时获取⾃增1字段ID的当前值,⽽⽆须再进⾏⼀次查询来获取!因为我⽴即要⽤到该ID值,如果在增加记录完毕后再利⽤select  id  进⾏⼀次查询⽆疑会使系统受限,有办法吗?
如果你能保证id=⾏数的话可以⽤
2、什么叫做SQL注⼊,如何防⽌?请举例说明
SQL注⼊就是在正常的SQL执⾏语句中恶意插⼊攻击者想要运⾏的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]--,那么后果不堪设想,如果我通过sql来执⾏net use相关的命令,就可能在服务器上给⾃⼰加⼀个帐号,这样就逐步可以控制整个数据库所在的服务器。。。
这就是sql注⼊的通常⽅法和可能的损害。
要放置其实也很简单,可以通过⾄少两个⽅法来进⾏:
1.最根本的,不实⽤组合sql的⽅法,⽽是通过使⽤命令参数⽅式来执⾏命令,⽐如我们把sql改成这种⽅式:
string strSql = "select * from [user] where LoginName and Pwd ";
,然后通过sqlcommand来执⾏它,就可以从根本上解决这个问题。
2.控制参数的长度。因为要想进⾏sql注⼊的话,需要⼀定长度的字符串才能执⾏,如果我们规定LoginName 的长度最长不超过8个,⼀般不会造成损害,当然这个只是在特殊的情况下才使⽤,⽐如有些情况可能不能使⽤命令参数⽅式。
点评:
sql注⼊是我们编程时必须考虑的问题,特别是BS的程序,更是要严格检查是否有sql注⼊的漏洞。最关键的⼀点是,你要明⽩怎么解决这个问题,⼀般⾯试⼈员会希望你提⾼使⽤参数⽅式来防⽌注⼊。
3、游标的作⽤?如何知道游标已经到了最后?
关系数据库中的操作会对整个⾏集起作⽤。由 SELECT 语句返回的⾏集包括满⾜该语句的 WHERE ⼦句中条件的所有⾏。这种由语句返回的完整⾏集称为结果集。应⽤程序,特别是交互式联机应⽤程序,并不总能将整个结果集作为⼀个单元来有效地处理。这些应⽤程序需要⼀种机制以便每次处理⼀⾏或⼀部分⾏。游标就是提供这种机制的对结果集的⼀种扩展。
游标的特点是:
允许定位在结果集的特定⾏。
从结果集的当前位置检索⼀⾏或⼀部分⾏。
⽀持对结果集中当前位置的⾏进⾏数据修改。
为由其他⽤户对显⽰在结果集中的数据库数据所做的更改提供不同级别的可见性⽀持。
提供脚本、存储过程和触发器中⽤于访问结果集中的数据的 Transact-SQL 语句
在从游标中提取信息后,可以通过判断@@FETCH_STATUS 的值来判断是否到了最后。当@@FETCH_STATUS为0的时候,说明提取是成功的,否则就可以认为到了最后。
点评:
游标是进⾏数据库操作的⼀个重要概念,但是在现代的软件开发中应⽤的不是很多,只有在⼀些特殊的存储过程中才会应⽤。但是,毕竟这是⼀个很重要,也是我们必须掌握的概念,最好能理解它的原理和⽤法。
4、SQL Server的两种索引是何形式?索引的作⽤?索引的优缺点?
sql server的索引分为聚集索引和⾮聚集索引,下⾯分别说明:
聚集索引
聚集索引根据数据⾏的键值在表或视图中排序和存储这些数据⾏。索引定义中包含聚集索引列。每个表只能有⼀个聚集索引,因为数据⾏本⾝只能按⼀个顺序排序。
只有当表包含聚集索引时,表中的数据⾏才按排序顺序存储。如果表具有聚集索引,则该表称为聚集表。如果表没有聚集索引,则其数据⾏存储在⼀个称为堆的⽆序结构中。
⾮聚集索引
⾮聚集索引具有独⽴于数据⾏的结构。⾮聚集索引包含⾮聚集索引键值,并且每个键值项都有指向包含该键值的数据⾏的指针。
从⾮聚集索引中的索引⾏指向数据⾏的指针称为⾏定位器。⾏定位器的结构取决于数据页是存储在堆中还是聚集表中。对于堆,⾏定位器是指向⾏的指针。对于聚集表,⾏定位器是聚集索引键。
索引的作⽤主要是为了在查询时提⾼查询的效率,并且尽量减⼩更新时的开销。
优点:
设计良好的索引查询效率可以得到极⼤的提⾼,某些情况下甚⾄可以提⾼⼏百上千倍。
缺点:
需要占⽤额外的空间和资源。在更新时耗费的时间更⼤,因为对数据的更新很有可能会导致索引的更新,这样就会导致增加系统开销。
点评:
在所有的进⾏系统优化的选择中,索引都是第⼀位的,⼀个设计良好的数据库肯定需要⾼超的索引设计技巧,在这⽅⾯效率提⾼不是⼀倍两倍的问题,⽽是可能会有质的飞跃,对索引优化的重要性,在⼀个⼤型项⽬⾥,怎么说都不为过。但是,索引优化⼜是⽐较困难的,哪些列需要加⼊索引,列的顺序怎样,哪个索引需要设置为聚集索引等等,都是我们必须要考虑的问题。
5、事务是什么?
事务是单个的⼯作单元。如果某⼀事务成功,则在该事务中进⾏的所有数据修改均会提交,成为数据库中的永久组成部分。
如果事务遇到错误且必须取消或回滚,则所有数据修改均被清除。
也就是说,事务是由⼀系列的“原⼦”操作组成的,这些原⼦操作必须全部完成,否则所有的动作都会被取消并恢复到初始状态。
开始事务使⽤BEGIN TRANSACTION 语句显,以 COMMIT 或 ROLLBACK 语句结束。
以上是针对数据库来说的。
但是,事务不仅仅限于数据库,数据库以外的动作也可以被组合进事务中,⼀般称为“企业级事务”。举⼀个例⼦:我们有这两个操作必须都完成,即在向数据库插⼊⼀条记录后必须在硬盘的某个⽂件夹内创建⼀个⽂件,这个就是⼀个企业级事务,它超出了简单的数据库事务的范畴。我们可以通过编程来实现企业级事务。
点评:
事务是数据库开发中⼀个⾮常重要的概念,它对与保证数据库的完整性和⼀致性⾮常重要。对于事务的的C#代码实现更是务必要熟练掌握。
6、存储过程和函数的区别
存储过程,功能强⼤,可以执⾏包括修改表等⼀系列数据库操作,也可以创建为 SQL Server 启动时⾃动运⾏的存储过程。
⾃定义函数,⽤户定义函数不能⽤于执⾏⼀组修改全局数据库状态的操作。
存储过程,可以使⽤⾮确定函数。
⾃定义函数,不允许在⽤户定义函数主体中内置⾮确定函数。
存储过程,可返回记录集。
⾃定义函数,可以返回表变量,也可以有任意个输出参数,
存储过程,其返回值不能被直接引⽤,必须单独调⽤
⾃定义函数,其返回值可以被直接引⽤,也就是可以直接 select * from 函数

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。