在SQL Server 2000中,VARCHAR的最大长度是8000,如果字符串的长度超过8000,保存在VARCHAR中时就会被截断。
也不能定义DECLARE @largeText TEXT ,常见的字符串函数也不能使用,除了datalength,substring(substring中英文字符作为一个字符)。

这几个数据类型在行为上和较小的数据类型 varchar、nvarchar 和 varbinary 相同,最大长度都为2^31-1。

微软的说法是用这个数据类型来代替之前的text、ntext 和 image 数据类型,它们之间的对应关系为:

varchar(max)——-text;

nvarchar(max)—–ntext;

varbinary(max)—-image.

注意:
1.VARCHAR和VARCHAR(MAX)混在一起做处理时还是会变成VARCHAR,从而可能被截断,所以需要全转成VARCHAR(MAX)

2.在变量声明中使用 char 和 varchar 数据类型时,这些数据类型的默认值 n 为 1。

3.在 CAST 和 CONVERT 中使用 varchar 时,显示 n 的默认值为30。

MSSQL2005新增了四个排名函数,ROW_NUMBER, RANK, DENSE_RANK, NTILE。利用这些函数可以有效地分析数据以及向查询的结果行提供排序值。

建立测试数据,分析它们各自的作用。

CREATE TABLE [Test]
(
     [StudentID] [bigint] NOT NULL,
     [ClassID] [bigint] NOT NULL,
     [TestScore] [decimal](4, 1) NOT NULL
) ON [PRIMARY]
 GO

 INSERT INTO [Test]  VALUES (100001,100,90) 
 INSERT INTO [Test]  VALUES (100002,100,85.5)
 INSERT INTO [Test]  VALUES (100003,100,80)
 INSERT INTO [Test]  VALUES (100004,100,80)
 INSERT INTO [Test]  VALUES (100005,100,74)
 INSERT INTO [Test]  VALUES (101001,101,94)
 INSERT INTO [Test]  VALUES (101002,101,85.5)
 INSERT INTO [Test]  VALUES (101003,101,85.5)

测试代码:

 SELECT *, 
      ROW_NUMBER() OVER (ORDER BY TestScore DESC) as RN,
      RANK() OVER (ORDER BY TestScore DESC) as R,
      DENSE_RANK() OVER (ORDER BY TestScore DESC) as DR,
      NTILE(3) OVER (ORDER BY TestScore DESC) as N3
 FROM [Test]

执行结果:

StudentID ClassID  TestScore   RN    R   DR   N
--------- -------- ----------- ----- --- ---- -
101001    101      94.0        1     1   1    1
100001    100      90.0        2     2   2    1
100002    100      85.5        3     3   3    1
101002    101      85.5        4     3   3    2
101003    101      85.5        5     3   3    2
100003    100      80.0        6     6   4    2
100004    100      80.0        7     6   4    3
100005    100      74.0        8     8   5    3

通过以上的例子就很清晰了。

ROW_NUMBER
行号函数。用来生成数据行在结果集中的序号
语法:
ROW_NUMBER( ) OVER ([] )

可以利用ROW_NUMBER函数非常便利的实现分页功能

RANK
排序函数。必须配合over函数,且排序字段值相同的行号一样,同时隐藏行号会占位。
语法:
RANK() OVER ([] )

还可以利用partition进行分组排序,例如对每个班级分别按成绩排序。

DENSE_RANK
紧凑排序函数。与RANK函数不同的是,当排序字段值相同导致行号一样时,同时隐藏行号不占位。
语法:
DENSE_RANK ( ) OVER ([] )
NTILE
分区排序函数。NTILE函数需要一个参数N,这个参数支持bigint。这个函数将结果集等分成N个区,并按排序字段将已排序的记录依次轮流放入各个区内。最后每个区内会从1开始编号,NTILE函数返回这个编号。
语法:
NTILE (integer_expression) OVER ([]< order_by_clause>)

SET ROWCOUNT { number | @number_var }

使 SQL Server 在返回指定的行数之后停止处理查询。 要将此选项设置为 off 以便返回所有的行,请将 SET ROWCOUNT 指定为 0。
SET ROWCOUNT 的设置是在执行时或运行时设置,而不是在分析时设置。

和TOP合用

如果行数值较小,则 SET ROWCOUNT 将覆盖 SELECT 语句 TOP 关键字。

当 INSERT、UPDATE 和 DELETE 语句使用显式 TOP 表达式时,这些语句将忽略 SET ROWCOUNT。这包括 INSERT 后跟 SELECT 子句的语句。

影响范围

设置 SET ROWCOUNT 选项将使大多数 Transact-SQL 语句在受到指定数目的行影响后停止处理。这包括触发器和 INSERT、UPDATE 及 DELETE 等数据修改语句。ROWCOUNT 选项对动态游标无效,但它可以限制键集的行集和不区分游标。应谨慎使用该选项,它主要与 SELECT 语句一起使用。

在 SQL Server 的下一个版本中,使用 SET ROWCOUNT 将不会影响 DELETE、INSERT 和 UPDATE 语句。
对于当前使用 SET ROWCOUNT 的 DELETE、INSERT 和 UPDATE 语句,建议您使用 TOP 语法重写它们。
对于在远程表和本地及远程分区视图上执行的 INSERT、UPDATE 和 DELETE 语句,将忽略 SET ROWCOUNT 选项设置。

select top

在MSSQL2000中是不支持select top + 变量的形式的
在MSSQL2005中却可以,例如:
select top 语句支持变量数目,如下例:

declare @n int
set @n=10
select top(@n) from orders

这样在后台存储过程分页就可以不必用动态语句了。。。

简介

ROW_NUMBER()是MS SQL Server 2005中新增窗口函数,可用来直接生成行号(但是SQL Server 2000中是没有这个函数的)。如:

select ROW_NUMBER() over (order by ENo), ENo,EName  
from Employee 

主要作用

分页

select * from (select orderid,freight,row_number() over(order by freight) as row from Orders) a
where row between 20 and 30

结合通用表达式进行分页

WITH OrderFreight AS( 
    select OrderId, Freight, ROW_NUMBER() OVER(order by Freight) as row from Orders 
) 
select OrderId, Freight from OrderFreight where row between 10 and 20

mssql2000模拟方法

1、使用临时表。

如果是在存储过程中,这是一个不错的选择。
创建一个临时表,其中除了需要的查询结果外,还一个记数列。查询结果放入临时表后(一般情况下可直接使用Insert into语句),用代码进行记数,更新记数列的值。
在记数列数值的生成方法上,还有一个改进的办法是直接将该列定义为自增长字段。这样“记数”的代码也省掉了。

2、采用自连接。

如果是在代码中,不便于使用临时表,可以采用此方法。比如执行一个查询统计,需要一个替代的SQL语句。
这个方法实际上是通过表的自连接给结果行“分等级”的思路来实现的。
语句如下:

select count(*),e1.ENo, e1.EName  
from Employee e1  
inner join Employee e2 on e1.ENo >= e2.ENo  
group by e1.ENo, e1.EName  
order by 1  

或者把join条件放到where子句中:

select count(*),e1.ENo, e1.EName  
from Employee e1, Employee e2,   
where e1.ENo >= e2.ENo  
group by e1.ENo, e1.EName  
order by 1  

如果ENo字段值不重复,还可以这样写:

select (select count(*) from Employee e2 where e1.ENo >= e2.ENo), e1.ENo, e1.EName  
from Employee e1  
order by 1  

如果ENo字段值有重复的情况,要使用最后一种写法可以将where条件变通一下,如:

where e1.ENo+e1.EName >= e2.ENo+e2.EName

总能找到不存在重复值的表达式的。

表变量

定义
一种特殊的数据类型,用于存储结果集以供后续处理。该数据类型主要用于临时存储一组行,这些行将作为表值函数的结果集返回。
尽可能使用表变量而不使用临时表。
表变量有以下特点
  • 1.表变量的行为类似于局部变量,有明确定义的作用域。该作用域为声明该变量的函数、存储过程或批处理。
    在其作用域内,表变量可像常规表那样使用。该变量可应用于 SELECT、INSERT、UPDATE 和 DELETE 语句中用到表或表的表达式的地方。但是,表不能用在下列语句中:
    INSERT INTO table_variable EXEC 存储过程。
    SELECT select_list INTO table_variable 语句。
  • 2.在定义表变量的函数、存储过程或批处理结束时,自动清除表变量。
  • 3·表类型声明中的 CHECK 约束、DEFAULT 值和计算列不能调用用户定义函数。
  • 4·在存储过程中使用表变量与使用临时表相比,减少了存储过程的重新编译量。
  • 5·涉及表变量的事务只在表变量更新期间存在。这样就减少了表变量对锁定和记录资源的需求。
  • 6·不支持在表变量之间进行赋值操作。
    declare @t1 table(t1 int)
    declare @t2 table(t2 int)
    set @t1=@t2 –错误
  • 7·另外,由于表变量作用域有限,并且不是持久数据库的一部分,因而不受事务回滚的影响。

临时表

本地临时表
本地临时表,本地临时表的名称前面有一个编号符 (#table_name).如果本地临时表由存储过程创建或由多个用户同时执行的应用程序创建,则 SQL Server 必须能够区分由不同用户创建的表。为此,SQL Server 在内部为每个本地临时表的表名追加一个数字后缀。存储在 tempdb 数据库的 sysobjects 表中的临时表,其全名由 CREATE TABLE 语句中指定的表名和系统生成的数字后缀组成。为了允许追加后缀,为本地临时表指定的表名 table_name 不能超过 116 个字符。

除非使用 DROP TABLE 语句显式除去临时表,否则临时表将在退出其作用域时由系统自动除去:

当存储过程完成时,将自动除去在存储过程中创建的本地临时表。由创建表的存储过程执行的所有嵌套存储过程都可以引用此表。但调用创建此表的存储过程的进程无法引用此表。

所有其它本地临时表在当前会话结束时自动除去。

全局临时表
全局临时表的名称前面有两个编号符 (##table_name)。
全局临时表在创建此表的会话结束且其它任务停止对其引用时自动除去。任务与表之间的关联只在单个 Transact-SQL 语句的生存周期内保持。
换言之,当创建全局临时表的会话结束时,最后一条引用此表的 Transact-SQL 语句完成后,将自动除去此表。

在存储过程或触发器中创建的本地临时表与在调用存储过程或触发器之前创建的同名临时表不同。如果查询引用临时表,而同时有两个同名的临时表,则不定义针对哪个表解析该查询。嵌套存储过程同样可以创建与调用它的存储过程所创建的临时表同名的临时表。嵌套存储过程中对表名的所有引用都被解释为是针对该嵌套过程所创建的表。

当创建本地或全局临时表时,CREATE TABLE 语法支持除 FOREIGN KEY 约束以外的其它所有约束定义。如果在临时表中指定 FOREIGN KEY 约束,该语句将返回警告信息,指出此约束已被忽略,表仍会创建,但不具有 FOREIGN KEY 约束。在 FOREIGN KEY 约束中不能引用临时表。
考虑使用表变量而不使用临时表。当需要在临时表上显式地创建索引时,或多个存储过程或函数需要使用表值时,临时表很有用。通常,表变量提供更有效的查询处理。

-- 说明: T-SQL 中没有"默认值对象"和"默认值约束"的区别, 而是统称为"默认值". 这里仅为了讨论方便.   
--      所谓"默认值对象", 指作为 CREATE DEFAULT 语句的一部分创建的默认值定义;   
--      所谓"默认值约束", 指作为 CREATE TABLE 或 ALTER TABLE 语句的一部分创建的默认值定义.   
-- 注意: 后续版本的 Microsoft SQL Server 将删除由 CREATE DEFAULT 语句创建的默认值定义, 应使用  
--      通过 ALTER TABLE 或 CREATE TABLE 的 DEFAULT 关键字创建的默认定义.   
  
-- 1. 创建"默认值对象"   
create default df_Test as 100;   
go   
  
-- 2. 创建测试表    
create table t_Tab1   
(  
    c1 smallint identity,   
    c2 smallint          null                         default 2, -- 作为 CREATE TABLE 语句的一部分创建匿名的"默认值约束"   
    c3 smallint          null,   
    c4 smallint          null constraint df_t_Tab1_c4 default 4, -- 作为 CREATE TABLE 语句的一部分创建命名的"默认值约束"   
    c5 smallint          null,   
    c6 smallint          null,   
    c7 smallint          null    
);   
  
create table t_Tab2   
(  
    c1 smallint identity,   
    c2 smallint null,   
    c3 smallint null   
);   
go  
  
-- 3. 作为 ALTER TABLE 语句的一部分创建匿名的和命名的"默认值约束"   
alter table t_Tab1 add constraint df_t_Tab1_c6 default 6 for c6;   
alter table t_Tab1 add                         default 7 for c7;   
go   
  
-- 4. 将"默认值对象" df_Test 绑定到列上   
--     ! 同一个"默认值对象"既可同时绑定到同一个表的不同列上, 也可同时绑定到不同表的列上.   
execute sp_bindefault df_Test, N't_Tab1.c3';   
execute sp_bindefault df_Test, N't_Tab1.c5';   
execute sp_bindefault df_Test, N't_Tab2.c2';   
-- 作为 CREATE TABLE 语句的一部分创建的命名的"默认值约束"不能绑定到其它表上.   
-- execute sp_bindefault df_t_Tab1_c6, N't_Tab2.c3';   
  
-- 作为 CREATE DEFAULT 语句的一部分创建的"默认值对象", 不能通过 ALTER TABLE 绑定到列上.   
-- alter table t_Tab1 add df_Test for c3;   
-- alter table t_Tab1 add df_Test default for c3;   
-- alter table t_Tab1 add constraint df_Test default for c3;   
go   
  
-- 5. 测试默认值   
insert into t_Tab1 default values;   
insert into t_Tab1 default values;   
insert into t_Tab1 default values;   
select * from t_Tab1;   
go   
   
insert into t_Tab2 default values;   
insert into t_Tab2 default values;   
insert into t_Tab2 default values;   
select * from t_Tab2;   
go    
  
-- 6. 通过 sys.default_constraints 目录视图, 检测不到作为 CREATE DEFAULT 语句的一部分创建的"默认值对象".   
SELECT sys.objects.name             表名,   
       sys.columns.column_id        列ID,   
       sys.columns.name             列名,   
       sys.default_constraints.name 默认值约束名   
FROM sys.default_constraints INNER JOIN sys.columns   
    ON sys.default_constraints.parent_object_id = sys.columns.object_id   
        AND sys.default_constraints.parent_column_id = sys.columns.column_id   
    INNER JOIN sys.objects   
    ON sys.columns.[object_id] = sys.objects.[object_id]   
WHERE sys.objects.name = N't_Tab1';   
go   
  
-- 7. "默认值对象", 命名的"默认值约束", 匿名的"默认值约束"都是"架构范围内的对象", 并且其 type 均是 D = DEFAULT(约束或独立).   
select name into t_Temp from sys.objects where type = 'D';   
select name as [架构范围内 type 为 D 的数据库对象名] from t_Temp;    
go   
  
-- 8. "默认值对象"是"默认值", 但不是"默认值约束"; 命名或匿名的"默认值约束"不是"默认值", 却是"默认值约束".   
select name                                                as [架构范围内 type 为 D 的数据库对象名],   
       OBJECTPROPERTY(OBJECT_ID(name, N'D'), N'IsDefault') as IsDefault   
from t_Temp;   
  
select name                                                    as [架构范围内 type 为 D 的数据库对象名],   
       OBJECTPROPERTY(OBJECT_ID(name, N'D'), N'IsDefaultCnst') as IsDefaultCnst   
from t_Temp;   
  
drop table t_Temp;   
go   
  
-- 9. 为列解除(删除)默认值绑定   
--     #1 不能对"表名"使用 sp_unbindefault 来解除其所有列上的默认值绑定   
-- execute sp_unbindefault N't_Tab1';   
--     #2 解被除绑定了"默认值对象"的列的正确方法   
execute sp_unbindefault N't_Tab1.c3';   
execute sp_unbindefault N't_Tab1.c5';   
execute sp_unbindefault N't_Tab2.c2';   
--     #3 对命名或匿名的"默认值约束", 不能使用 sp_unbindefault 的方法来解除绑定; 需要使用 ALTER TABLE DROP CONSTRAINT 来解除.   
-- execute sp_unbindefault N't_Tab1.c2';   
-- execute sp_unbindefault N't_Tab1.c4';   
go   
  
-- 10. 要删除用户定义的默认值(即, "默认值对象"), 必须首先解除它与列的绑定.   
--     这里 df_Test 与列绑定的解除已经在 9 中完成, 所以可以删除了.   
drop default df_Test;   
go   
  
-- 11. 删除绑定了默认值的列  
--     说明: 假如一个列上绑定了默认值, 则删除该列之前, 必须先解除其默认值绑定.   
--          如果绑定的是"默认值对象", 通过 sp_unbindefault 来解除;   
--          如果绑定的是"默认值约束"(命名或匿名的), 通过 ALTER TABLE DROP CONSTRAINT 来解除.   
  
-- 12. 删除表创建的数据库对象    
drop table t_Tab1;   
drop table t_Tab2;   
go   

执行结果:
已将默认值绑定到列。  
已将默认值绑定到列。  
已将默认值绑定到列。  
  
(1 行受影响)  
  
(1 行受影响)  
  
(1 行受影响)  
c1     c2     c3     c4     c5     c6     c7  
------ ------ ------ ------ ------ ------ ------  
1      2      100    4      100    6      7  
2      2      100    4      100    6      7  
3      2      100    4      100    6      7  
  
(3 行受影响)  
  
  
(1 行受影响)  
  
(1 行受影响)  
  
(1 行受影响)  
c1     c2     c3  
------ ------ ------  
1      100    NULL  
2      100    NULL  
3      100    NULL  
  
(3 行受影响)  
  
表名       列ID      列名        默认值约束名  
-------- -------- --------- --------------------------  
t_Tab1   2        c2        DF__t_Tab1__c2__3AD78439  
t_Tab1   4        c4        df_t_Tab1_c4  
t_Tab1   6        c6        df_t_Tab1_c6  
t_Tab1   7        c7        DF__t_Tab1__c7__3EA8151D  
  
(4 行受影响)  
  
  
(5 行受影响)  
架构范围内 type 为 D 的数据库对象名  
-------------------------------------  
df_Test  
DF__t_Tab1__c2__3AD78439  
df_t_Tab1_c4  
df_t_Tab1_c6  
DF__t_Tab1__c7__3EA8151D  
  
(5 行受影响)  
  
架构范围内 type 为 D 的数据库对象名       IsDefault  
------------------------------------- -----------  
df_Test                               1  
DF__t_Tab1__c2__3AD78439              0  
df_t_Tab1_c4                          0  
df_t_Tab1_c6                          0  
DF__t_Tab1__c7__3EA8151D              0  
  
(5 行受影响)  
  
架构范围内 type 为 D 的数据库对象名       IsDefaultCnst  
------------------------------------- -------------  
df_Test                               0  
DF__t_Tab1__c2__3AD78439              1  
df_t_Tab1_c4                          1  
df_t_Tab1_c6                          1  
DF__t_Tab1__c7__3EA8151D              1  
  
(5 行受影响)  
  
已解除了表列与其默认值之间的绑定。  
已解除了表列与其默认值之间的绑定。  
已解除了表列与其默认值之间的绑定。  

别名的位置:

hkey_local_machine-software-Microsoft–MSSQLSERVER-Client-ConnectTo

别名的格式:

名称:数据库别名名称
类型:REG_SZ
数值:
DBMSSOCN,主机地址,端口
比如:DBMSSOCN,192.168.1.111,8000

自动导入脚本:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo]
“SQL2005TCP”=”DBMSSOCN,192.168.1.111,8000”

另存为reg后缀的文件即可。

用户定义的数据类型要放在使用他的数据库里才有效,由于存储过程中建立的临时表会建立在tempdb里面,所以要先在tempdb里执行,再在mastrer里执行
查看用户定义的数据类型:

sql2005: select * from sys.types where is_user_defined=1
sql2000:select * from systypes where xtype<>xusertype

自定义数据类型
建立在SQL server系统数据类型基础上的,需要指定该类型的名称,建立在其上的系统数据类型及是否充许为空。
方法:利用系统存储过程:sp_addtype
语法:sp_addtype type, [ system_data_type ] [ ,’nulltype’ ]
注:

1 .type是用户定义数据类型的名称。数据类型名称必须遵循标识符规则,并且在每个数据库中必须是唯一的。
2 .system_data_type是SQL server提供的数据类型,用户定义的数据类型即基于该类型。
3 . ‘ nulltype ‘ :指定必须如何处理null值。设置null默认, not null或nonull

例1:自定义数据类型taihang
exec sp_addtype taihang,smllint, ‘ not null ‘
例2:删除自定义数据类型taihang
exec sp_droptype taihang

–创建用户定义类型方法一:
CREATE TYPE SSN
FROM varchar(11) NOT NULL ;
–删除用户定义类型
drop type SSN

–定义两个用户定义类型方法二:
exec sp_addtype iq, ‘float’, ‘null’
exec sp_addtype shoesize, ‘float’,’null’

–指定约束条件
create rule iq_range as @range between 1 and 200
create rule shoesize_range as @range between 1 and 20

–绑定约束类型
exec sp_bindrule ‘iq_range’,’iq’
exec sp_bindrule ‘shoesize_range’,’shoesize’

–删除用户定义类型
exec sp_droptype iq
exec sp_droptype shoesize