8说明:
1.本内容是对《网络程序设计-ASP》、《网络程序设计—ASP案例教程》、《网络程序设计基础》的补充教程,部分内容节选自其中章节。
2.如有任何问题,请到www.jjshang的BBS论坛上讨论。
3.其它网站可以转载,但是任何单位和个人不得将其用于商业活动。
4.尚俊杰 2005-3-27
在ASP中如何正确书写SQL字符串
尚俊杰
在学习ASP的过程中,很多同学在书写SQL字符串时都感到比较困难,总是发生各种
各样的错误,并且对其中的双引号、单引号和连接运算符&感到非常难以掌握。本文就从头
开始系统讲述一下如何书写正确的SQL字符串,并给出一个比较有效的调试方法。
1 双引号、单引号和连接运算符&
首先声明:这里说的符号是英文状态下的符号,也可以说是语法中用到的符号。
因为在书写SQL语句时,最常见的困惑就是对其中的双引号、单引号和连接运算符&
的理解。下面就从基础讲起。
(1)关于双引号
在ASP中,用到字符串常数时两边要加上双引号 " ,表示其中是一个字符串,如下面
都是字符串常数:
"abcdefg"
"伟大的祖国"
"101"
"2003-10-5"
大家可能会想,101是一个数字啊,2003-10-5是一个日期啊。但是,只要在两边加上
了双引号,那么它就是一个字符串,不管其中的内容是数字还是英文字母还是中文。
(2)关于单引号
有同学可能会想了,你现在用双引号表示其中是一个字符串,但是假如在字符串中间也
用到了双引号,那么岂不就会出现这样的情况:
"ab"cde"fg"
这样显然就会引起别人的误解,到底第一个双引号和第几个双引号配套呢?因为ASP
规定,当出现双引号嵌套时,可以将内层的双引号转变为单引号 ' 或者转变两个连续的双
引号 ""。按照该规定,上面的字符串应该改写为如下形式:
"ab'cde'fg"
"ab""cde""fg"
8说明:
1.绝大部分情况下,发生引号嵌套时,大家可以将内层引号改成单引号,即第一种形式。
2.特殊情况下,需要使用第二种形式。因为这两者有一定区别,在使用他们时,第1种形式中间就是一个单引号,而第二种形式中间其实是一个双引号,大家可以利用
Response.Write 语句将它们输出到页面上比较结果。
不过,需要说明的是,这里说的引号嵌套都是针对英文状态下的字符说的,如果在字符
串中间有中文状态下的引号,则不必替换。如下面的字符串都是合法的:
"伟大的“祖国”万岁"
"伟大的“祖国万岁"
这也提示我们,在处理客户提交的数据时,如果客户输入的都是中文字符,那么,不管
输入了什么,都可以当作一个字符串。但是,如果客户输入的是英文,那么就可能会发生字
符串嵌套的情况。
(3)连接运算符&
在使用字符串时,我们经常需要将两个或多个字符串连接成一个大的字符串,这时就需
要用到连接运算符&(此时也可以用+,不过一般用&),如下:
"abcd" & "efg"
"abcd" & "efg" & "hijk"
对于上面两个表达式,执行连接运算后结果如下:
"abcdefg"
"abcdefghijk"
我们来看一下其中的连接运算原理,以第一个表达式为例,它实际上是先将两个双引号
之间的内容abcd去出来,然后再将第二个字符串之中的内容efg取出来,将它们连到一起
变成abcdefg。当然,它们的结果自然还是字符串常数,所以,仍然要在两边添加双引号,
表示中间的是字符串常数,因此就变成了最后的"abcdefg"。
对于第二个表达式,本质上和上面一样,只不过是先将第一个字符串和第二个字符串连
接成一个字符串,然后再将它们的结果和第三个字符串连接成最后的字符串。
8说明:
1.有的同学想出了一个形式上的理解方法,说是将中间的" & "擦去,然后连到一起就行了。结果是一样的,不过真正的原理还是以上面为准。
2.对于"abcd" & "efg",在ASP中也可以将&两边的空格去掉,成为"abcd"&"efg"。不过,推荐加上空格,这样程序会清楚些。
3.有时候,表达式中可能有更多的连接运算符。运算过程也是一样的,从左到右依次进行即可。
上面的例子比较简单,如果中间也有单引号,可能会变得复杂些。不过你只要记住,不
管其中有无单引号,一个字符串两边的双引号之间的内容都是这个字符串的内容,连接时都
要取出来,你只要将其中的单引号当成普通的字符即可。如下面的例子:
"ab'cd'efg" & "hi'jk'lmn"
执行连接运算后,结果如下:
"ab'cd'efghi'jk'lmn"
至于具体原理仿照上面的讲解即可。将第一个字符串中的内容ab'cd'efg和第二个字符串
中的内容hi'jk'lmn取出来连到一起,变成ab'cd'efghi'jk'lmn,然后在两边加上双引号,表示
这是一个字符串常数"ab'cd'efghi'jk'lmn"。
好,现在相信大家对于双引号、单引号和连接运算符的概念已经比较清楚了,可能还有
的同学会进一步提出,上面的例子("abcd" & "efg")好像意义不大啊,这个式子直接写成
sql语句替换表中内容"abcdefg",何苦要将其分成两部分,中间再加个连接符,这不多此一举吗?
这个想法其实是对的,在实际使用中,尽管有时也用&连接两个字符串常数,但是更多的时候是将一个字符串常数和一个字符串变量连接到一起,或者是将两个字符串变量连接到一起。如下:
"ab'cd'efg" & strTemp
大家可以注意到,上面的表达式中,第一项是一个字符串常数,第二项是一个字符串变量。那么它们是怎么执行连接运算呢?其实很简单:
假如strTemp="hi'jk'lmn",那么将其代入到上面表达式,那么上面的表达式就变成了"ab'cd'efg" & "hi'jk'lmn"
后面的运算原理和前面的讲述也就一样了,最后结果为"ab'cd'efghi'jk'lmn"
还有人喜欢写成这样:
strSql="ab'cd'efg"
strSql=strSql & strTemp
这是两条语句,执行完毕后其实和上面的结果是一样的。它的过程是:在第一句中将"ab'cd'efg"保存到变量strSql中,在第二句中从变量中取出字符串,再和字符串变量strTemp 连接到一起,重新保存到变量strSql中。
假如strTemp="hi'jk'lmn",那么执行完毕后变量strSql中的内容为"ab'cd'efghi'jk'lmn"。
(4)一个常犯的错误:将字符串变量写到了字符串常数中
这里要特别强调一个常犯的错误,就是将字符串变量直接写到了字符串常数中,如对于上面的表达式,个别同学写成了
"ab'cd'efgstrTemp"
他认为这就是将字符串常数"ab'cd'efg"和字符串变量strTemp连接到一起了。可是,除了他自己,别人谁能看出strTemp是一个字符串变量呢?
其实在这个错误的写法中,strTemp这几个字符和前面的ab'cd'efg字符没有任何本质区别。系统不会将其当作字符串变量,而只会把它们看作是这个大字符串的一部分内容。或者说,这就是一个字符串常数,其中的内容是ab'cd'efgstrTemp。
因此,大家一定要记住,字符串变量不能直接写到字符串常数中。在希望将一个字符串常数和一个字符串变量连接到一起时,一定要使用&(或+)将它们连接到一起。如:"ab'cd'efg" & strTemp
当然,如果希望将两个字符串变量连接到一起,也是一样的,如:
strTemp1 & strTemp2
还有,有时会将几个字符串常数和几个字符串变量连接到一起,如:
"ab'cd'efg" & strTemp & "hi'jk'lmn"
它们的运算原理和过程都一样,将字符串变量的内容代入到表达式中,然后执行连接运算。
2 书写正确的SQL字符串
深刻掌握上面一节后,其实就可以比较容易的书写SQL字符串了。因为本质上,SQL 字符串也就是一个普通的字符串,不管使用字符串常数还是字符串变量,总之最后你要将它们连接成一个符合一定格式要求的字符串而已。
8首先强调:SQL语言有如下规定,在SQL字符串中
1.文本型、备注型字段对应的字段值两边要加引号。
2.数字、自动编号、布尔型两边什么都不用加。
3.日期字段对应的子段值两边要加 # 号,在SQL数据库中改用引号。
4.自动编号字段不用自己添加,数据库会自动添加。
下面举例讲解,要提前说明的是下面主要以Insert语句为主,其实Select、Update、Delete 等语句也大
同小异:
假如有一个数据库,其中有下面的数据表users,包含包含下面的字段,字段都是默认设置:
字段1 ID 自动编号(该字段实际不需要插入,系统自动插入)
字段2 username 文本型(也就是字符串型)(用户名)
字段3 age 数字型(年龄)
字段4 birthday 日期型(生日)
字段5 marry 布尔型(是否结婚,结婚为True,未结婚为False)
字段6 intro 备注型(简介)
2.1 在SQL字符串中插入文本型、备注型字段值
(1)一个最简单的SQL字符串
先来看一个很简单的SQL语句。
Insert Into users(username) values("小王")
大家来看一下,这是一个标准的SQL语句,因为username是文本型字段,所以字段值两边要加双引号,表示小王是一个字符串。
上面的SQL语句是可以直接在Access的查询中执行的。可是在ASP程序中,SQL语句是当作一个字符串来处理的,因此我们通常这样写
strSql="Insert Into users(username) values('小王')"
此时,前后的双引号表示中间是一个字符串。而小王两边的单引号是因为发生了引号嵌套,所以内层引号改为了单引号。
(2)在SQL字符串中使用字符串变量
实际插入记录时,因为“小王”通常是从表单中获取的,如Request.Form(“username”),当然也可以将其保存到一个字符串变量myusername中。
不过前面第1节特别提到过,字符串变量不能直接写到字符串常数中,必须用&和字符串常数连接到一起,因此,上面的例子要改成下面的形式:
strSql="Insert Into users(username) values('" & myusername & "')"
个别同学此时就糊涂了,为什么其中又有单引号,又有双引号,还有连接运算符啊?其实,仔细回忆一下上一节讲述的内容,就会发现并不复杂。
在这条语句等号右边的表达式中,其实包括如下三部分内容,两个字符串常数和一个字符串变量,它们之间用连接运算符连接到一起:
第一部分字符串常数:"Insert Into users(username) values('"
第二部分字符串变量:myusername
第三部分字符串常数:"')"
这几部分容易引起糊涂的是,为什么第一部分后面是一个单引号和一个双引号啊?为什么第三部分开头是一个双引号和一个单引号啊。其实,对于第一部分来说,两边的双引号就表示中间的内容是一个字符串常数,其中的单引号'和别的字符一样,只是这个字符串常数的内容而已。同理,对于第三部分,两边的双引号表示这是一个字符串常数,中间的单引号
和括号')就是它的内容。
理解清楚每一部分的组成后,有同学可能会问,我现在知道这就是一个字符串常数连接一个字符串变量,再连接一个字符串常数,其中的单引号和双引号我也知道怎么回事了。可是你为什么要这样写呢?为什么我就想不到这样写。
其实,这要从我们的最终目标来看,假如用户输入的用户名(username字段)是“小王”,那么我们最后实际需要的就是如下的SQL字符串。
strSql="Insert Into users(username) values('小王')"
因为客户输入的是“小王”,所以,字符串变量myusername = "小王",将它代入到下面的表达式中:
strSql="Insert Into users(username) values('" & myusername & "')"
就变成了
strSql="Insert Into users(username) values('" & "小王" & "')"
依次执行两个连接运算符,将右边的三部分连接成一个字符串,最后结果如下。
strSql="Insert Into users(username) values('小王')"
可以看到,这就是我们最终需要的SQL字符串。现在可以看清楚了,原来第一部分中的单引号和第三部分中的单引号就是现在小王两边的单引号,表示小王是一个字符串。
(3)使用两个字符串变量
上面的例子只有一个字段比较简单,下面给一个两个字段的例子。假如现在要插入两个字段值,username和intro(intro字段是备注型,字段值两边也要加引号)。
strSql="Insert Into users(username,intro) values('" & myusername & "','" & myintro & "')"
在这个表达式中,myusername和myintro都是字符串变量,分别保存用户名和用户简介信息。现在就来剖析这个表达式。
等号右边其实是如下五部分组成的:
第一部分字符串常数:"Insert Into users(username,intro) values('"
第二部分字符串变量:myusername
第三部分字符串常数:"','"
第四部分字符串变量:myintro
第五部分字符串常数:"')"
现在还是将字符串变量代入后来理解。假如myusername="小王",myintro="一个好孩子",那么代入后就变成了
strSql="Insert Into users(username,intro) values('" & "小王" & "','" & "一个好孩子" & "')"
依次执行四个连接运算符,结果如下:
strSql="Insert Into users(username,intro) values('小王','一个好孩子')"
大家可以看到,这是一个正确的SQL字符串,因为这两个字段值两边都要加引号,所以原来的字符串常数中才有好几个单引号。其中第一部分和第三部分开头的单引号是小王两边的,第三部分后面和第五部分中的单引号是一个好孩子两边的。
如果添加更多的子段值,请大家依次类推。
2.2 在SQL字符串中插入数字型和布尔型字段值
前面提到过,在SQL字符串中,数字型和布尔型字段值两边什么都不用加,想对比较简单。
(1)插入数字型字段
假如插入一个年龄为12的记录,最终的SQL字符串应该如下:
strsql="Insert into users(age) values(12) "
如果现在年龄是一个变量myage,则应该为:
strsql="Insert into users(age) values(" & myage & ") "
这里等号右边也是三部分,分别如下:
第一部分字符串常数:"Insert into users(age) values("
第二部分数字变量:myage
第三部分字符串常数:")"
这里需要注意的是数字变量myage在这个表达式中会自动转换成字符串,假如myage=12,那么实际上代入为"12",就变成了
strsql="Insert into users(age) values(" & "12" & ") "
继续执行连接运算符,就变成了如下我们需要的最终结果。
strsql="Insert into users(age) values(12) "
(2)插入布尔型字段
布尔型的解释和上面是一样的,只不过它只有两个值 True和False,如:
strsql=“Insert into users(marry) values(True)”
如果换成布尔变量mymarry
strsql=“Insert into users(marry) values(” & mymarry & “)”
2.3 在SQL字符串中插入日期型字段值
日期型和文本型类似,但是要将单撇号替换为#号。(不过,Access数据库中用单撇号也可以)
strsql=“Insert into users(birthday) values(#2005-3-1#)”
如果换成日期变量mydate,则应该如下:
strsql=“Insert into users(birthday) values(#” & mydate & “#)”
这里也要特别说明的是日期变量mydate会自动转换为字符串代入,如将mydate=#2005-3-1#代入后实际为:
strsql=“Insert into users(birthday) values(#” & "2005-3-1" & “#)”
执行连接运算符,结果如下:
strsql=“Insert into users(birthday) values(#2005-3-1#)”
需要特别注意的两点:
(1)有很多人经常在这里使用日期函数Date()或Now(),你只要将其也看作变量就可以了。如:
strsql=“Insert into users(birthday) values(#” & Date() & “#)”
(2)在SQL数据库中,这里不能用#号,也要用单引号,就好比是一个文本型字段值。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论