知识点一:
using (cmd = new SqlCommand("insert into category(name) values('@caName')",GetConn()))
注意这个没有分奥,然后和if 语句一样,当满足条件的时候,运行代码块中的内容。
知识点二:
建表注意事项:
对于建表大家都不陌生,这里主要说明一下几点注意实现:
1、大数据字段最好剥离出单独的表,以便影响性能
2、使用varchar,代替char,这是因为varchar会动态分配长度,char指定为20,即时你存储字符“1”,它依然是20的长度
3、给表建立主键,看到好多表没主键,这在查询和索引定义上将有一定的影响
4、避免表字段运行为null,如果不知道添加什么值,建议设置默认值,特别int类型,比如默认值为0,在索引查询上,效率立显。
5、建立索引,聚集索引则意味着数据的物理存储顺序,最好在唯一的,非空的字段上建立,其它索引也不是越多越好,索引在查询上优势显著,在频繁更新数据的字段上建立聚集索引,后果很严重,插入更新相当忙。
6、组合索引和单索引的建立,要考虑查询实际和具体模式.
SQL语句注意事项:
熟悉SQL的人,都会写SQL语句,但到底效率如何,十万以下的数据量,根本没任何区别,但一些基础性的东西,还是得点滴做起
1、where语句的书写,当有多个查询条件时,sql是按照从右往左的顺序进行执行,也就是说写在最后的条件会最早被执行,这就意味着过滤数据量最多的
添加应该写在最后,这样才能在性能上达到最优
2、join语句,如果A表1000w,B表30条记录,则应该是A join B,sql执行会以B为准去关联A,性能显著
3、表变量和临时表 ,这个问题可能有些同学稍陌生,所谓表变量就是declare @dd table类似这样的声明,而临时表多见#tt,这样的格式这二者在sql内是区别对待的表变量功能有限,使用完自动释放,临时表计划就是有数据表的大部分功能,使用完毕后需要删除,在数据库tempdb也有对应的操作记录,使用时应该综合考虑。
4、注意聚合函数,is null,<>等的使用,当我们在这样使用的时候,可能习以为常,在大数据量处理上,本有的索引将不再被使用,而变成全表扫描,So ga等吧,性能大大的慢,如where len(studentId)=0,本来在studentid上的索引变成全表扫描了。
5、使用exist代替not in,这个大家都知道,但还是希望大家注意下
6、select AA,BB,代替Select * ,这是大部分程序员的通病,总觉得无所谓,其实select * 在sql执行时还是要遍历到具体的字段名进行读取,即使我们要使用全部列,也推荐使用把各个字段都罗列处理,而非使用*
7、top n 和order by 你了解多少?我一直觉得where条件查询完后order by在此基础上进行排序,其实错了,在有top n和order by一块使用时,order by竟然是全表扫描,具体可以通过查询计划验证。
8、编码过程和单元测试过程尽量用数据量较大的数据库测试,最好能用实际数据测试
9、不要频繁更新有触发器的表的数据
知识点三:
在SQL SERVER 2008中,有三种类型的触发器:
- DML触发器:是指触发器在数据库中发生数据操作语言(DML)事件时将启用。DML事件即指在表或视图中修改数据的insert、update、delete语句也。
- DDL触发器:是指当服务器或数据库中发生数据定义语言(DDL)事件时将启用。DDL事件即指在表或索引中的create、alter、drop语句也。
- 登陆触发器:是指当用户登录SQL SERVER实例建立会话时触发
知识三:触发器
实例
代码什么的,时间一久,就对面不识了;但是 那些能够给人眼前一亮的技能呀,真是一学就会。牛腩系统就是溜。
小技巧们:
1. if() 然后小碎步走起,双击tab,就自动补全了。
2. 自定义方法,要想显示特有的注释,怎么破?
注释方法:
///summary 序言注释
模块注释:
# region
# end region
类注释: 再懒些可以创建模板。每次新建的时候,使用模板就好了。
/*
*
*
*/
3. // TODO
4. 代码块复用
错误:
ERROR 1:
解决方法:
ERROR 2 :
从 varchar 数据类型到 datetime 数据类型的转换产生一个超出范围的值
不仅是日期小于1753-01-01会报错,日期不对也会报错
数据类型 | 时间范围 | 精度 |
---|---|---|
datetime | 1753-01-01到9999-12-31 00:00:00 到 23:59:59.997 | 毫秒 |
smalldatetime | 1900-01-01 到 2079-06-06 00:00:00 到 23:59:59 | 分钟 |
date | 0001-01-01 到 9999-12-31 | 天 |
time | 00:00:00.0000000 到 23:59:59.9999999 | 100 纳秒 |
datetime | 2 0001-01-01 到 9999-12-31 00:00:00 到 23:59:59.9999999 | 100 纳秒 |
datetimeoffset | 0001-01-01 到 9999-12-31 00:00:00 到 23:59:59.9999999 -14:00 到 +14:00 | 100 纳秒 |
ERROR 3
raiserror
RAISERROR (50005, -- Message id.
10, -- Severity,
1, -- State,
N'abcde'); -- First argument supplies the string.
EEROR 4
try-catch -finally
结论:
1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
举例:
情况1:try{} catch(){}finally{} return;
显然程序按顺序执行。
情况2:try{ return; }catch(){} finally{} return;
程序执行try块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,最后执行try中return;
finally块之后的语句return,因为程序在try中已经return所以不再执行。
情况3:try{ } catch(){return;} finally{} return;
程序先执行try,如果遇到异常执行catch块,
有异常:则执行catch中return之前(包括return语句中的表达式运算)代码,再执行finally语句中全部代码,
最后执行catch块中return. finally之后也就是4处的代码不再执行。
无异常:执行完try再finally再return.
情况4:try{ return; }catch(){} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,因为finally块中有return所以提前退出。
情况5:try{} catch(){return;}finally{return;}
程序执行catch块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,因为finally块中有return所以提前退出。
情况6:try{ return;}catch(){return;} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
则再执行finally块,因为finally块中有return所以提前退出。
无异常:则再执行finally块,因为finally块中有return所以提前退出。
最终结论:任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
编译器把finally中的return实现为一个warning。