表变量

定义
一种特殊的数据类型,用于存储结果集以供后续处理。该数据类型主要用于临时存储一组行,这些行将作为表值函数的结果集返回。
尽可能使用表变量而不使用临时表。
表变量有以下特点
  • 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 约束中不能引用临时表。
考虑使用表变量而不使用临时表。当需要在临时表上显式地创建索引时,或多个存储过程或函数需要使用表值时,临时表很有用。通常,表变量提供更有效的查询处理。

别名的位置:

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

  当使用JDBC 通过 Microsoft SQL Server 2000/2005 Driver for JDBC 检索 ResultSet 对象可能会报如下错误:
Java.sql.SQLException: [Microsoft] [SQL Server 2000 JDBC Driver] ResultSet can not re-read row data for column 1

这是Microsoft数据库驱动包的一个Bug,这里有介绍:http://support.microsoft.com/kb/824106

包含 BLOB 列 (例如对于 文本、 ntext 或 图像 数据类型) 的 结果集 对象,将发生此错误。驱动程序不能返回 BLOB 列的顺序,因为它不缓存的大小限制由于 BLOB 数据类型的所有内容。结果集 集中的任何行的从左到右,可以阅读任何列,并应只一次读取每一列。如果您尝试将阅读顺序,列,或者从 结果集 中重新读取列您可能会收到"症状"部分描述的错误消息。

就是说我们在执行select * from table这样的语句是可能会有此提示消息。我们可以改为select 具体的列 from table这样的语句出错可能性就小了。

最好的方法是用非官方提供的驱动包,比如jTDS驱动包替代Microsoft的原有驱动包。具体链接语句如下:

private String driver= "net.sourceforge.jtds.jdbc.Driver";
private String url="jdbc:jtds:sqlserver://localhost:1433/kalman03";

官方和JTDS驱动下载:SQL2000Driverforjdbc(jtds支持Microsoft SQL Server (6.5, 7.0, 2000 and 2005) 和Sybase)

 

JTDS介绍:

 

  JTDS是一个开放源代码的100%纯Java的,用于JDBC 3.0驱动Microsoft SQL Server (6.5 ,7 ,2000和2005版本)和Sybase(10 ,11 ,12 ,15 版本)的驱动程序 。 JTDS是基于freetds的,并且是目前最快的生产准备JDBC驱动程序为SQL Server和Sybase 。 JTDS完全与JDBC 3.0兼容,支持只向前的,和可滚动/可更新的结果集(ResultSets)中并行(完全独立)语句,并且可实施所有databasemetadata和resultsetmetadata方法。注意低版本的JTDS(比如jtds-0.9.jar)对中文编码支持不是很好,建议采用较新的版本比如jtds-1.2.5.jar。