1、TRUNCATE 和 DELETE
TRUNCATE操作没有记录删除操作日志
主要的原因是因为 TRUNCATE 操作不会激活触发器,因为TRUNCATE操作不会记录各行删除操作的日志,所以当你需要删除一张表的数据时你需要考虑是否应该有删除操作记录日志,而不是根据个人的习惯来操作。
2、事务
[1]并不是事务中的任意一条语句报错整个事务都会回滚,其它的可执行成功的语句依然会执行成功并提交。
[2]TRY...CATCH
DELETE FROM Table1 BEGIN TRY BEGIN TRANSACTION INSERT INTO Table1(ID,Age) VALUES(1,20) INSERT INTO Table1(ID,Age) VALUES(2,20) INSERT INTO Table1(ID,Age) VALUES(3,20) INSERT INTO Table3 VALUES(1) COMMIT TRANSACTION END TRY BEGIN CATCH ROLLBACK TRANSACTION END CATCH ----重新打开一个回话执行查询,发现由于存在对象出错BEGIN CATCH并没有收到执行报错,且事务一直处于打开状态,没有被提交,也没有执行回滚。 SELECT * FROM Table1 ---如果事务已经提交查询XACT_STATE()的状态值是0,或者执行DBCC OPENTRAN SELECT XACT_STATE() DBCC OPENTRAN ---手动执行提交或者回滚操作 ROLLBACK TRANSACTION
TRY...CATCH 不会返回对象错误或者字段错误等类型的错误。
[3]打开XACT_ABORT
SET XACT_ABORT ON BEGIN TRANSACTION INSERT INTO Table1(ID,Age) VALUES(1,20) INSERT INTO Table1(ID,Age) VALUES(2,20) INSERT INTO Table1(ID,Age) VALUES(3,20) INSERT INTO Table3 VALUES(1)
COMMIT TRANSACTION
SET XACT_ABORT OFF ---事务全部执行回滚操作(对象table3是不存在报错,但是也回滚所有的提交,跟上面的TRY...CATCH的区别) SELECT * FROM Table1
---查询是否有打开事务 SELECT XACT_STATE() DBCC OPENTRAN 未查询到有打开事务 当 SET XACT_ABORT 为 ON 时,如果执行 Transact-SQL 语句产生运行时错误,则整个事务将终止并回滚。 当 SET XACT_ABORT 为 OFF 时,有时只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。如果错误很严重,那么即使 SET XACT_ABORT 为 OFF,
也可能回滚整个事务。OFF 是默认设置。 编译错误(如语法错误)不受 SET XACT_ABORT 的影响。
3、 条件字段的先后顺序
当你建索引的时候索引的顺序很重要,一般把查询最频繁的字段设第一个字段,可以避免建多余的索引。
所以这里我一般是这样规定where条件的,对于经常用作查询的字段放在第一个位置,其它的字段根据表的实际字段顺序排列,这样往往你的查询语句走索引的概率会更大。
4、外连接
[1]对于外连接,连接条件不会改变主表的数据,即不会删减主表的数据;
[2]无论你在连接条件on里面怎样设置主表的条件都不影响主表数据的输出,影响主表数据的输出只在where条件里,where条件影响最后数据的输出。而对于附表的条件就应该写在连接条件(on)里而不是where条件里,这里说的是外连接(包括左连接和右连接)。
[3]对于inner join就不存在这种情况,无论你的条件是写在where后面还是on后面都是一样的,但是还是建议写在where后面。
5、谓词类型要与字段类型对齐
[1]谓词类型与字段类型不一致,于定义表的字段类型与查询条件中该字段类型不一致,导致执行计划走了索引扫描,且执行计划select也有提示。
[2] 谓词类型与字段类型一致,所以查询走了索引查找。
6、Is Not Null 与 != (或 <>)区别
平时经常会遇到这两种写法:IS NOT NULL与!=NULL。也经常会遇到数据库有符合条件!=NULL的数据,但是返回为空集合。实际上,是由于对二者使用区别理解不透彻。
默认情况下,推荐使用 IS NOT NULL去做条件判断,因为SQL默认情况下对 Where 字段!= Null 的判断会永远返回0行,却不会提示语法错误。
原因:SQL Server文档中对Null值的比较运算定义了两种规则,如在SQL Server 2000中:
[1]ANSISQL(SQL-92)规定的Null值的比较取值结果都为False,既Null=Null取值也是False。
[2]另一种不遵循ANSISQL标准,即Null=Null为True。:
例如数据表test结构:
ROWNUM DATA ------------------- 1 'Liu Yang' 2 Null 3 '12345'
按照ANSI SQL标准,下面的两个查询都不返回任何行:
查询一: SELECT * FROM test WHERE data=NULL
查询二: SELECT * FROM test WHERE data<>NULL
而按照非ANSI SQL标准,查询1将返回第二行,查询2返回1、3行。
这是因为在SQL中,NULL是一种特有的数据类型,其等价于没有任何值、是未知数。NULL与0、空字符串、空格都不同。
ANSI SQL标准中取得Null值的行,需要用下面的查询:SELECT * FROM test WHERE data IS NULL
而非ANSI SQL标准中 data=NULL 等同于 data IS NULL,data<>NULL 等同于 data IS NOT NULL。
如果你一定要使用!= null来进行条件判断,需要加上这个命令语句:SET ANSI_NULLS OFF,这时数据库进入ANSI SQL非标准模式,你会发现IS NOT NULL 和 != null 是等效的了。
这里使用的是模式切换命令SET ANSI_NULLS[ON/OFF]。ON值采用ANSI SQL严格标准,OFF值采用非标准兼容模式。另外SET ANSI_DEFAULTS [ON/OFF]命令也可以实现标准的切换,只是这个命令控制的是一组符合SQL-92标准的设置,其中就包括Null值的标准。
默认情况下,数据库管理程序(DB-Library)是SET ANSI_NULLS为OFF的。但是我们的大多数应用程序,都是通过ODBC或者OLEDB来访问数据库的,作为一种开放兼容的数据库访问程序,或许是兼容性的考虑,SETANSI_NULLS值设置为ON。这样一来带来的一些问题是需要注意的。像存储过程或者自定义函数这样的应用程序都是基于DB-Library的,默认情况下,SETANSI_NULLS为OFF,并且在这样的程序中,不能使用SETANSI_NULLS在一个环境中修改规则,只能修改数据库配置参数。
例如下面这种情况:你的应用程序使用ADODB来访问数据库,采用OleDb或者ODBC数据提供程序。对于查询一: SELECT * FROM test WHERE data=NULL 我们可以直接发送命令取得查询结果集,也可把它放到存储过程当中。但二者查询结果不同。若直接使用查询命令,不返回任何行;而如果访问存储过程,返回第2行的数据。
最后,我们再次声明:数据库默认情况下,做SQL条件查询比较时使用关键字" is null " 和 " is not null "。