SQL Server 2005:数据类型最大值
来源:asp之家 发布时间:2009-06-04 09:55:00
事情开始得很简单。MegaWare公司市场部门想要一个新的网站来发布文档,开发团队觉得使用SQL Server 2000数据库作为文档存储仓库会使事情变得简单。Steve是MegaWare的数据库管理员,没有看出这有什么大问题;在数据库中存储文档,而不是使用文件系统,意味着服务器需要多做一些工作,但是它也会使得备份和管理容易得多。数据库与文件系统变得不同步也应该是不可能的。
市场部门想要存储的许多文档都超过了8000个字节,那么很明显VARCHAR不是适合这项工作的数据类型。作为替代,TEXT数据类型被用来定义存放数据的字段。因为每个TEXT都能容纳2GB的内容,TEXT要存放市场部门的同事们扔进数据库的最大的文件也是没有问题的。
数月过去了,市场用大量的无聊拷贝填满了整个数据库。但是这还不是Steve真正关心的问题。数据库愉快地嗡嗡作响地运转着,每个人对项目的结果都很满意。
直到公司的标语改变的那个重大的日子。市场部的团队认为“MegaWare: It's really cool!”要比原来的“It's MegaWare's Way or the Highway!” 听起来更好。因为市场部团队已经将原来的标语嵌入了仓库中每个文档的页脚上,现在Steve的工作就是更改所有这些文档的页脚。
“没有问题,” Steve想,打开SQL Server 查询分析器工具,执行了如下的T-SQL批处理:
UPDATE MarketingDocuments
SET Document =
REPLACE(Document,
'It''s MegaWare''s Way or the Highway!',
'MegaWare: It''s really cool!)
当他看到出现的错误消息的时候,Steve的轻松的微笑很快消失了,“替换函数的参数1,text数据类型无效。”
替换函数在编写出来的时候,就对TEXT数据类型不起作用。同样也对CHARINDEX或者SUBSTRING不起作用——或者至少是他们在超过8千个字符的情况下不起作用。更进一步地讲,开发人员忘了处理TEXT或者IMAGE类型的本地变量;实际上不支持任何操作。即使是简单地更新一个文档中的一个子字符串都需要用到晦涩的东西,以及难以使用的类似READTEXT和WRITETEXT的函数。而不是开发人员或者忙碌的数据库管理员因为想要弄清如何正确使用而采用了不同类型的函数消耗了时间。
SQL Server的开发人员很幸运,他们将会拨开乌云见蓝天。SQL Server 2005引入了一系列新的被称为MAX的数据类型。这是VARCHAR,NVARCHAR和VARBINARY类型的扩展,这几种类型以前被限制在8000字节以下。MAX可以容纳高达2GB的数据,与TEXT和IMAGE一样——并且完全兼容所有的SQL Server内置的字符串函数。
用MAX关键字定义一个某种MAX类型的变量与替代字符串的尺寸(为VARCHAR/NVARCHAR的时候)或者字节(为VARBINARY的时候)一样简单。
DECLARE @BigString VARCHAR(MAX)
SET @BigString = 'abc'
虽然这个变量可以自由地操纵,并且可以传递给任何的内置的字符串函数,兼容性仍然不是没有问题。首先,开发人员不能期望指定了尺寸的VARCHAR和VARBINARY变量在达到8000个字节的极限的时候可以自动“升级”到MAX版本。例如,如下的批处理:
DECLARE @String1 VARCHAR(4001)
DECLARE @String2 VARCHAR(4001)
SET @String1 = REPLICATE('1', 4001)
SET @String2 = REPLICATE('2', 4001)
SELECT LEN(@String1 + @String2)
4001+4001=8002,但是指定了尺寸的VARCHAR的极限是8000。因为这两个变量中没有一个是MAX类型,LEN函数的结果就是8000,不是8002。在将两个变量连接的时候,一种简单的修正方法就是声明这两个变量中的一个为VARCHAR(MAX)或者将其中的一个变量进行转换。与一个规定了尺寸的类型进行连接的时候,优先考虑MAX类型,最终结果是MAX类型。所以,以下批处理的结果是8002,正如我们期望的一样:
DECLARE @String1 VARCHAR(4001)
DECLARE @String2 VARCHAR(4001)
SET @String1 = REPLICATE('1', 4001)
SET @String2 = REPLICATE('2', 4001)
SELECT LEN(CONVERT(VARCHAR(MAX), @String1) + @String2)
在传递给字符串函数的时候,开发人员意识到字符串的原意在默认情况下是规定了尺寸的,而不是MAX类型,也是至关重要的。例如,以下查询的结果就很令人惊奇:
SELECT LEN(REPLICATE('1', 8002))
因为字符串‘1’是被作为规定了尺寸的VARCHAR对待,而不是VARCHAR(MAX),结果就是8000——但是在SQL Server 2005中,REPLICATE函数能够产生高达2GB的字符串。要修正这个问题,可以将字符串转换为VARCHAR(MAX),这样函数就会输出同样的类型了:
SELECT LEN(REPLICATE(CONVERT(VARCHAR(MAX), '1'), 8002))
这个查询现在将会返回期望的结果:8002。记住,总是要对采用了新特性编写的代码进行非常仔细的测试;隐藏的问题,例如上面描述的问题,可能并且毫无疑问地会在最坏的时间里造成灾难性的后果。
猜你喜欢
- 1、远程服务器上安装jupyter notebook(配置jupyter_notebook_config.py文件)sudo pip ins
- 前言所谓模糊查询就是不需要用户完整的输入或者说全部输入信息即可提供查询服务,也就是用户可以在边输入的同时边看到提示的信息(其实是查询出来匹配
- 在开发一个程序时候,与其让它运行时崩溃,不如在它出现错误条件时就崩溃(返回错误)。这时候断言assert 就显得非常有用。python as
- 我的电脑环境是使用.net framework4.5.1,如果在调试过程中调不通请注意我用的是Visual studion 2017,pyt
- vue中异步数据获取1、获取异步数据,通过async/await限制 import { fetchList } from '
- 本文实例讲述了Python 面向对象之封装、继承、多态操作。分享给大家供大家参考,具体如下:封装、继承、多态 是面向对象的3大特性为啥要封装
- 描述sin()返回的x弧度的正弦值。语法以下是sin()方法的语法:importmath math.sin(x)注意:sin()是不能直接访
- 传统的网页BBS大多是采用CGI模式实现的,它的实现要求编程者既要掌握编程语言如Perl或C等,又要了解关于CGI模式的各项技术内容,因此要
- 模块a.py 想用 b.py中公有数据 cntb的python文件#!/usr/bin/env python# coding:utf8fro
- 本文实例讲述了Django框架中间件(Middleware)用法。分享给大家供大家参考,具体如下:1、面向切面编程切点(钩子)切点允许我们动
- 实例如下:import os if __name__ == "__main__": file_path =
- opts, args = getopt.getopt(sys.argv[1:], "t:s:h", ["wal
- 阅读上一章:chapter 5 表单Chapter 6 <strong>,<em>与其他短语元素在引言和前面的章节中
- 不论什么语言,我们都需要注意性能优化问题,提高执行效率。选择了脚本语言就要忍受其速度,这句话在某种程度上说明了Python作为脚本语言的不足
- 【添加事件机制】 addEventListener 和 attachEvent[W3C]addEvent
- 沟通的时候,一般我不主动说自己是做用户体验设计,也不说做以用户为中心的设计,包括UED, UCD。这种专业名词传达的太虚,你也许是名用户体验
- 对于需要大量使用 http 请求的项目,我们通常会选择对 http 请求的方法进行二次封装,以便增加统一的 * ,或者统一处理阻止重复提交之
- 本文实例为大家分享了python购物车程序的具体代码,供大家参考,具体内容如下代码:''''' Cr
- SQLserver代理已经启动了,服务里的SQLServerAgent响应服务也已经开启了 但是启动作业的时候还是提示“错误22022:SQ
- 问题一:python启动报错api-ms-win-crt-process-l1-1-0.dll 丢失解决:下载api-ms-win-crt-