sql数据类型建表时如何选择数据类型
ntext和text⼀样⽤来保存⼤量的⽂字数据,不过text⽤单字节保存数据,ntext固定⽤双字节保存数据. ntext保存的是Uncode的字符, ntext ⽀持跨语⾔平台。
ntext:
可变长度 Unicode 数据的最⼤长度为 230 - 1 (1,073,741,823) 个字符。存储⼤⼩是所输⼊字符个数的两倍(以字节为单位)。ntext 在 SQL-92 中的同义词是 national text。
ntext中存数据是按双字节存的,显⽰不了NTEXT你换⼀下recordset打开⽅式就⾏了
text:
服务器代码页中的可变长度⾮ Unicode 数据的最⼤长度为 231-1 (2,147,483,647) 个字符。当服务器代码页使⽤双字节字符时,存储量仍是2,147,483,647 字节。存储⼤⼩可能⼩于 2,147,483,647 字节(取决于字符串)。
char、varchar、text和nchar、nvarchar、ntext的区别
1、CHAR。CHAR存储定长数据很⽅便,CHAR字段上的索引效率级⾼,⽐如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间,不⾜的⾃动⽤空格填充。
2、VARCHAR。存储变长数据,但存储效率没有CHAR⾼。如果⼀个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。VARCHAR类型的实际长度是它的值的实际长度+1。为什么“+1”呢?这⼀个字节⽤于保存实际使⽤了多⼤的长度。从空间上考虑,⽤varchar合适;从效率上考虑,⽤char合适,关键是根据实际情况到权衡点。
3、TEXT。text存储可变长度的⾮Unicode数据,最⼤长度为2^31-1(2,147,483,647)个字符。
4、NCHAR、NVARCHAR、NTEXT。这三种从名字上看⽐前⾯三种多了个“N”。它表⽰存储的是Unicode数据类型的字符。我们知道字符中,英⽂字符只需要⼀个字节存储就⾜够了,但汉字众多,需要两个字节存储,英⽂与汉字同时存在时容易造成混乱,Unicode字符集就是为了解决字符集这种不兼容的问题⽽产⽣的,它所有的字符都⽤两个字节表⽰,即英⽂字符也是⽤两个字节表⽰。nchar、nvarchar的长度是在1到4000之间。和char、varchar⽐较起来,nchar、nvarchar则最多存储4000个字符,不论是英⽂还是汉字;⽽char、varchar最多能存储8000个英⽂,4000个汉字。可以看出使⽤nchar、nvarchar数据类型时不⽤担⼼输⼊的字符是英⽂还是汉字,较为⽅便,但在存储英⽂时数量上有些损失。
对于什么时候⽤varchar和nvarchar没有说⼀定的.
也就是说⼀个汉字既可以存在varchar中,也可以存在nvarchar中.
那么对于汉字或者Unicode 数据到底存在varchar和nvarchar有什么区别呢?
下⾯例⼦说明⼀下:⼀个汉字占varchar(2),只占nvarchar(1),⽽字母只占varchar(1),那么在数据库字段求长度的时候,⽤varchar你就不⼀定知道它确切的知道它到底有⼏个字,如果⽤nvarchar,那么汉字也是nvarchar(1),字母也是nvarchar(1),那么已经很明显了.
区别2:varchar的检索快于nvarchar,虽然是这样但微软下⼀个版本将统⼀nvarchar,听说的
管理 ntext、text 和 image 数据
Microsoft® SQL Server™ 的 ntext、text 和 image 数据类型在单个值中可以包含⾮常⼤的数据量(最⼤可
达 2 GB)。单个数据值通常⽐应⽤程序在⼀个步骤中能够检索的⼤;某些值可能还会⼤于客户端的可⽤虚拟内存。因此,
在检索这些值时,通常需要⼀些特殊的步骤。
如果 ntext、text 和 image 数据值不超过 Unicode 串、字符串或⼆进制串的长度(分别为 4,000 个字符、8,000 个字
符和 8,000 个字节),就可以在 SELECT、UPDATE 和 INSERT 语句中引⽤它们,其引⽤⽅式与较⼩的数据类型相同。例
如,包含短值的 ntext 列可以在 SELECT 语句的选择列表中引⽤,这与 nvarchar 列的引⽤⽅式相同。引⽤时必须遵守⼀
些限制,例如不能在 WHERE ⼦句中直接引⽤ ntext、text 或 image 列。这些列可以作为返回其它数据类型(例如varchar2最大长度
ISNULL、SUBSTRING 或 PATINDEX)的某个函数的参数包含在 WHERE ⼦句中,也可以包含在 IS NULL、IS NOT NULL 或
LIKE 表达式中。
处理较⼤的数据值
但是,如果 ntext、text 和 image 数据值较⼤,则必须逐块处理。Transact-SQL 和数据库 API 均包含使应⽤程序可以
逐块处理 ntext、text 和 image 数据的函数。
数据库 API 按照⼀种通⽤的模式处理长 ntext、text 和 image 列:
若要读取⼀个长列,应⽤程序只需在选择列表中包含 ntext、text 或 image 列,并将该列绑定到⼀个程序变量,该变量
应⾜以容纳适当的数据块。然后,应⽤程序就可以执⾏该语句,并使⽤ API 函数或⽅法将数据逐块检索到绑定的变量中。
若要写⼊⼀个长列,应⽤程序可使⽤参数标记 (?) 在相应位置代替 ntext、text 或 image 列中的值,以执⾏ INSERT
或 UPDATE 语句。参数标记(对 ADO ⽽⾔则为参数)被绑定到⼀个⾜以容纳数据块的程序变量上。应⽤程序进⼊循环,在
循环中先将下⼀组数据移到绑定的变量中,然后调⽤ API 函数或⽅法写⼊数据块。这⼀过程将反复进⾏,直到整个数据值
发送完毕。
使⽤ text in row
在 Microsoft SQL Server 2000 中,⽤户可以在表上启⽤ text in row 选项,以使该表能够在其数据⾏中存储 text、
ntext 或 image 数据。
若要启⽤该选项,请执⾏ sp_tableoption 存储过程,将 text in row 指定为选项名并将 on 指定为选项值。BLOB(⼆进
制⼤对象:text、ntext 或 image 数据)⾏中可以存储的默认最⼤⼤⼩为 256 字节,但是值的范围可以从 24 到 7000。
若要指定默认值以外的最⼤⼤⼩,请指定该范围内的整数作为选项值。
如果应⽤下列条件,则将 text、ntext 或 image 字符串存储在数据⾏中:
启⽤ text in row。
字符串的长度⽐ @OptionValue 所指定的限制短
数据⾏中有⾜够的可⽤空间。
当 BLOB 字符串存储在数据⾏中时,读取和写⼊ text、ntext 或 image 字符串可以与读取或写⼊字符串和⼆进制字符串
⼀样快。SQL Server 不必访问单独的页以读取或写⼊ BLOB 字符串。
如果 text、ntext 或 image 字符串⽐⾏中所指定的限制或可⽤空间⼤,则将指针存储在该⾏中。在⾏中存储 BLOB 字符
串的条件仍然适⽤,但是:数据⾏中必须有⾜够的空间容纳指针。
有关更多信息,请参见 sp_tableoption。
使⽤⽂本指针
如果未指定 text in row 选项,text、ntext 或 image 字符串将存储在数据⾏外;只有这些字符串的⽂本指针驻留在数
据⾏中。⽂本指针指向由内部指针⽣成的树的根节点,⽽这些内部指针映射到实际存储(text、ntext 或 image 数据的) 字符串段的页。
SQL Server 2000 中的⾏⽂本指针与 SQL Server 早期版本中的⽂本指针不同。⾏⽂本指针的⾏为就象 BLOB 数据的⽂件 句柄;早期的⽂本指针功能则象 BLOB 数据的地址。因此,在使⽤⾏⽂本指针时,请记住下列特性:
重要虽然游标中允许有⾏⽂本,但却不允许有⾏⽂本指针。如果尝试声明包含⾏⽂本指针的游标,SQL Server 将返回错 误信息(8654、16、1、"A cursor plan could not be generated for the given statement because it contains
textptr(inrow lob)."、1033)。
数字
对于每个数据库,每个事务最多允许 1024 个活动⾏⽂本指针。
锁定
当⽤户获取活动⽂本指针时,SQL Server 2000 在第⼀个⽤户控制⽂本指针时锁定数据⾏,并确保没有其他⽤户修改或删 除该⾏。锁在⽂本指针变为⽆效时被释放。若要使⽂本指针⽆效,请使⽤ sp_invalidate_textptr。
当事务的隔离级别是未提交读或者数据库为"只读"模式时,⽂本指针不能⽤于更新 BLOB 值。
当数据库为"单⽤户"模式时,SQL Server 2000 不锁定数据⾏。
为举例说明,给出下⾯的表:
CREATE TABLE t1 (c1 int, c2 text)
EXEC sp_tableoption 't1', 'text in row', 'on'
INSERT t1 VALUES ('1', 'a')
下⾯的事务将会成功:
INSERT t1 VALUES ('1','This is text.')
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
GO
BEGIN TRAN
DECLARE @ptr varbinary(16)
SELECT @ptr = textptr(c2)
FROM t1
WHERE c1 = 1
READTEXT t1.c2 @ptr 0 5
GO
下⾯的事务将会失败:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
GO
BEGIN TRAN
DECLARE @ptr varbinary(16)
SELECT @ptr = textptr(c2)
FROM t1
WHERE c1 = 1
WRITETEXT t1.c2 @ptr 'xx'
COMMIT TRAN
GO
持续时间
⾏⽂本指针仅在事务内有效。提交事务时,⽂本指针变为⽆效。
在某个事务内,当发⽣下列任⼀操作时,⾏⽂本指针可能⽆效:
会话结束。
删除该事务中的数据⾏。(其它事务⽆法删除数据⾏,因为该⾏包含锁。)
⽂本指针所在的表的架构已更改。使⽂本指针⽆效的架构更改操作包括:创建或除去聚集索引,改变或除去表,截断表, 通过 sp_tableoption 更改 text in row 选项,以及执⾏ sp_indexoption。
使⽤前⾯的⽰例,下列脚本在 SQL Server 早期版本中有效,但在 SQL Server 2000 中将⽣成错误。
DECLARE @ptrval varbinary(16)
PRINT 'get error here'
SELECT @ptrval = TEXTPTR(c2)
FROM t1
WHERE c1 = 1
READTEXT t1.c2 @ptrval 0 1
在 SQL Server 2000 中,必须在事务内使⽤⾏⽂本指针:
BEGIN TRAN
DECLARE @ptrval varbinary(16)
SELECT @ptrval = TEXTPTR(c2)
FROM t1
WHERE c1 = 1
READTEXT t1.c2 @ptrval 0 1
COMMIT
NULL ⽂本
可以在由 INSERT ⽣成的 NULL ⽂本上获得⾏⽂本指针。⽽在以前,只有将 BLOB 更新为 NULL 后才能获得⽂本指针。
例如,下列代码在 SQL Server 7.0 中⽆效,但在 SQL Server 2000 中有效。
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
GO
INSERT INTO t1 VALUES (4, NULL)
BEGIN TRAN
DECLARE @ptrval VARBINARY(16)
SELECT @ptrval = TEXTPTR(c2)
FROM t1
WHERE c1 = 4
WRITETEXT t1.c2 @ptrval 'x4'
COMMIT
在 SQL Server 7.0 中,必须执⾏下列操作:
INSERT INTO t1 VALUES (4, NULL)
UPDATE t1
WHERE c1 = 4
DECLARE @ptrval VARBINARY(16)
SELECT @ptrval = TEXTPTR(c2)
FROM t1
WHERE c1 = 4
WRITETEXT t1.c2 @ptrval 'x4'
下表汇总差别。
差别⾏⽂本指针⾮⾏⽂本指针
数字对于每个数据库,每个事务最多允许 1024 个活动⾏⽂本指针。⽆限制。
锁定将数据⾏⼀直 S 锁定到指针变为⽆效为⽌。
当事务为"未提交读"或数据库为"单⽤户"或"只读"模式时不获取锁。
不锁定数据⾏。
持续时间事务或会话结束、删除⾏或更改表的架构时变为⽆效。删除⾏时变为⽆效。
NULL ⽂本插⼊ NULL ⽂本后可⽴即获取。只有更新后才能获取。
通过数据库 API 使⽤ ntext、text 和 image 数据
这⼀部分概述数据库 API 处理 ntext、text 和 image 数据的⽅式:
ADO
ADO 可以将 ntext、text 或 image 列或参数映射为 Field 或 Parameter 对象。使⽤ GetChunk ⽅法逐块检索数据,使
⽤ AppendChunk ⽅法逐块写数据。有关更多信息,请参见管理 Long 数据类型。
OLE DB
OLE DB 使⽤ ISequentialStream 接⼝⽀持 ntext、text 和 image 数据类型。ISequentialStream::Read ⽅法逐块读取
长数据,ISequentialStream::Write ⽅法将长数据逐块写⼊数据库。有关更多信息,请参见 BLOB 和 OLE 对象。
ODBC
ODBC 具有⼀种称为"执⾏中的数据"的功能,可⽤于处理长数据的 ODBC 数据类型:SQL_WLONGVARCHAR (ntext)、
SQL_LONGVARCHAR (text) 和 SQL_LONGVARBINARY (image)。这些数据类型被绑定到某个程序变量上。这样⼀来,就可以调 ⽤ SQLGetData 逐块检索长数据,调⽤ SQLPutData 逐块发送长数据。有关更多信息,请参见管理 text 和 image 列。
DB-Library
DB-Library 应⽤程序也是将 ntext、text 和 image 列绑定到程序变量上。DB-Library 函数 dbtxtptr ⽤于获取指向数
据库中长列出现位置的指针,dbreadtext 则⽤来逐块读取长数据。dbwritetext、dbupdatetext 和 dbmoretext 之类的函
数⽤于逐块写⼊长数据。
说明不⽀持使⽤ DB-Library 访问⾏⽂本。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论