版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
SQL基础知识大全
SQL语言由命令、子句、运算和集合函数等构成。在SQL中,数据定义语言DDL(用来
建立及定义数据表、字段以及索引等数据库结构)包含的命令有CREATE、DROP、ALTER;
数据操纵语言DML(用来提供数据的查询、排序以及筛选数据等功能)包含的命令有
SELECT,INSERT.UPDATE>DELETE。
一、SQL语句
(1)Select查询语句
语法:SELECT[ALLIDISTINCT]<目标歹ij表达式〉[AS列名]
[,〈目标列表达式〉IAS列名]...JFROMv表名〉I,〈表名
[WHERE(条件表达式>[ANDIOR〈条件表达式
[GROUPBY列名[HAVING<条件表达式
[ORDERBY歹!]名[ASCIDESC]]
解释:[ALLIDISTINCT]ALL:全部;DISTINCT:不包括重复行
〈目标列表达式》对字段可使用AVG、COUNT、SUM、MIN、MAX、运算符等
〈条件表达式>
查询条件谓词
IL斗父=、
确定范围BETWEENAND.NOTBETWEENAND
确定集合IN、NOTIN
字符匹配LIKE("%”匹配任何长度,“一”匹配一个字符)、NOTLIKE
空值ISNULL、ISNOTNULL
子查询ANY、ALL、EXISTS
集合查询UNION(并)、INTERSECT(交)、MINUS(差)
多重条件AND、OR、NOT
<GROUPBY列名〉对查询结果分组
[HAVING〈条件表达式>]分组筛选条件
[ORDERBY列名[ASCIDESC]]对查询结果排序;ASC:升序DESC:降序
例1:selectstudent.snoas学号,as姓名,courseas课程名,scoreas成绩from
score,studentwherestudent.sid=score.sidandscore.sid=:sid
例2:selectstudent.snoas学号,as姓名,AVG(score)as平均分from
score,studentwherestudent.sid=score.sidandstudent.class=:classand(term=5orterm=6)group
bystudent.sno,havingcount(*)>0orderby平均分DESC
例3:select*fromscorewheresidlike'9634'
例4:select*fromstudentwhereclassin(selectclassfromstudentwherename='陈小小')
(2)INSERT插入语句
语法:INSERTINTO〈表名>[(<字段名1>[,〈字段名2>,...])]VALUES(〈常量1>[,<常量
2>,...])
语法:INSERTINTO(表名>[(V字段名1>[,<字段名2>,…])]子查询
例子:INSERTINTO借书表(rid.bookidx.bdate)VALUES(edit1.text,edit2.text,date)
例子:INSERTINTOscorel(sno,name)SELECTsno,nameFROMstudentWHEREclass='9634’
(3)UPDATE-SQL
语法:UPDATE〈表名〉
SET列名1二常量表达式列名2=常量表达式2...]
WHEREv条件表达式,[ANDIOR〈条件表达式
例子:updatescoresetcredithour=4wherecourse:'数据库,
(4)DELETE-SQL
语法:DELETEFROM〈表名〉[WHERE<条件表达式〉[ANDIOR<条件表达式>...]]
例子:Deletefromstudentwheresid=,OO310T
(5)CREATETABLE
CREATETABLEIDBFTableNamel[NAMELongTableName][FREE]
(FieldNamelFieldType[(nFieldWidth[,nPrecision])]
[NULLINOTNULL]
[CHECKlExpression1[ERRORcMessageTextl]]
[DEFAULTeExpression1]
[PRIMARYKEYIUNIQUE]
[REFERENCESTableName2[TAGTagNamel]]
[NOCPTRANS1
[,FieldName2...]
[,PRIMARYKEYeExpression2TAGTagName2
I,UNIQUEeExpression3TAGTagName3]
[,FOREIGNKEYeExpression4TAGTagName4[NODUP1
REFERENCESTableName3[TAGTagName5]]
[,CHECKlExpression2[ERRORcMessageText2]])
IFROMARRAYArrayName
(6)ALTERTABLE
ALTERTABLETableNamel
ADDIALTERLCOLUMNJFieldNamel
FieldType[(nFieldWidth[,nPrecision])]
[NULLINOTNULL]
[CHECKlExpression1[ERRORcMessageTextl]]
[DEFAULTeExpression1J
[PRIMARYKEYIUNIQUE]
[REFERENCESTableName2"AGTagName1JJ
[NOCPTRANS1
(7)DROPTABLE
DROPTABLE[路径名.]表名
(8)CREATEINDEX
CREATEINDEXindex-nameONtable-name(column[,column...])
例:CREATEINDEXuspaON口令表(user,password)
(9)DROPINDEX
DROPINDEXtable-name.index-namelPRIMARY
例:DROPINDEX口令表.uspa
二、在程序中使用静态SQL语句
在程序设计阶段,将SQL命令文本作为TQuery组件的SQL属性值设置。
三、在程序中使用动态SQL语句
动态SQL语句是指在SQL语句中包含有参数变量的SQL语句(如:select*fromstudent
whereclass=:class),在程序中可以为参数赋值。给参数赋值的方法有:
1、利用参数编辑器为参数赋值
选中TQuery组件,在对象监视器01中点取Params项,在弹出的参数编辑窗口中设置参
数的值。
例:SELECTbookidxAS书号,藏书表.booknameAS书名,bdateAS借书日期FROM借书
表,藏书表where借书表.bookidx=藏书表.bookidxandrid=:rid
2、在程序运行中通过程序为参数赋值
(1)根据参数在SQL语句中出现的顺序,使用TQuery的Params属性为参数赋值;
例:在借书表中插入•条记录
withQuery1do
begin
SQL.clear;
SQL.add('InsertInto借书表(bookidx,rid,rdate)f);
SQLadd('Values(:bookidx,:rid,:rdate)');
Params[0J.AsString:=bookidxEdit.Text;
Params[1].AsString:=ridEdit.Text;
Paramsl2J.AsDate:=date;
ExecSQL;
End;
(2)根据SQL语句中的参数名字,调用ParamByName方法为参数赋值;
ParamByNameC^ookidx').AsString:=bookidxEdit.Text;
ParamByName(,rid,).AsString:=ridEdit.Text;
ParamByName('rdate').AsDate:=date;
ExecSQL;
有:AsString、AsSmalllnt、Aslnteger、AsWord、AsBoolean、AsFloat、AsCurrency、
AsBCD、AsDate、AsTime、AsDateTime转换函数
3、使用数据源为参数赋值
把TQuery的DataSource属性设置为另一个数据源(TDataSource名字),Delphi会把未赋
值的参数与指定的数据源中的各字段相比较,并将匹配的字段的值赋给未赋值的参数,可实
现主表一明细表应用。
四、对TQuery返回的数据集进行修改
-一般情况下,TQuery返回的数据集是只读的,不能修改;
对不包含集操作(如:SUM、COUNT)的单表SELECT查询,设置TQuery的RequsetLive
属性为True,则可修改TQuery返回的数据集。
var
I:Integer;
Listitem:string;
begin
forI:=0toQuery1.ParamCount-1do
begin
Listitem:=ListBoxl.Items[I];
caseQuery1.ParamsfI].DataTypeof
ftString:
Queryl.Params[I].AsString:=Listitem;
ftSmalllnt:
Queryl.Params[I].AsSmallInt:=StrToIntDef(ListItem,0);
ftlnteger:
Queryl.Params[I].AsInteger:=StrToIntDef(ListItem,0);
ftWord:
Query1.Params[I].AsWord:=StrToIntDef(ListItem,0);
f(Boolean:
begin
ifListitem=True'then
Queryl.Params[I].AsBoolean:=True
else
Query1.Params[I].AsBoolean:=False;
end;
ftFloat:
Queryl.Params[I].AsFloat:=StrToFloat(ListItem);
ftCurrency:
Query!.Params[IJ.AsCurrency:=StrToFloat(Listltem);
ftBCD:
Query1.Params[IJ.AsBCD:=StrToCurr(Listltem);
ftDate:
Queryl.Params[IJ.AsDate:=StrToDate(Listltem);
ftTime:
Query1.Params[IJ.AsTime:=StrToTime(Listltem);
ftDateTime:
QueryI.Params[I].AsDateTime:=StrToDateTime(Listltem);
end;
end;
end;
2003-11-259:59:00
查看评语???
2003-11-2510:06:20运行期间对数据库表的
一、数据集表的打开与关闭
打开:设置数据集组件的Active属性为True或调用数据集组件的Open方法
关闭:设置数据集组件的Active属性为False或调用数据集组件的Close方法
二、创建数据库应用程序
?利用向导创建:使用Database菜单/FormWizard选项;
?创建主从表:设置从表的MasterSource、MaslerField属性;
?创建查询表:使用TQueiy组件;
三、数据库表记录的定位
?使用TDBNavigator组件;
?调用数据集组件的First、Next>Prior,Last方法;
?数据集组件的EOF属性(或BOF属性)用来判断记录指针是否指向第条记录(或最后
一条记录);
?使用数据集的书签BookMark(GetBookMark:获得当前记录的BookMark记号:
GotoBookMark:从当前记录直接转到指定BookMark的那条记录;FreeBookMark:释放某
个BookMark)
?使用GotoKeyFindKey方法查找记录进行定位;
四、数据库表字段对象的使用
(1)创建永久的字段对象
双击或单击再右击TTable(TQuery)对象打开字段编辑器,使用其弹出菜单增加字段对象、
删除字段对象、定义新的字段对象(字段编辑器的弹出菜单的NewFields选项,可创建计
算字段);
(2)字段对象的属性、方法、事件
字段对象名:如TablelName、Query1Sid
属性:Alignment(对齐方式)、Calculated(是否是从其它字段值计算得到)、DisplayLabel
(显示的标题)、DisplayWidth(显示的宽度)、DisplayFormat(显示的格式)、EditMask(输
入的限制)、FieldName(字段名)、Readonly(是否只读)、Visible(是否显示)
事件:OnChange(字段值发生变化时触发)、OnGetText(当字段对象获得字段值时触发)、
OnSetText(当字段对象被设置字段值时触发)、OnValiData(当修改、插入、进行有效性检
验时触发)
(3)字段对象的类型转换
有:AsString、AsSmalllnt、Aslnteger、AsWord、AsBoolean、AsFloat、AsCurrency、
AsBCD、AsDate、AsTime、AsDateTime转换函数
如:Edit1.Text:=Table1Name.Value;
Table1Bdate.AsString:=DateToStr(DATE);
(4)对字段对象的访问
动态字段对象的访问:Tablel.Fields[O].DisplayLabel:=学生编号’
Table1.FieldByName('Sid)DisplayLabel:='学生编号'Table1.Fields[O].Assignment:=taCenter
Editl.Text:=Table1,FieldByName('Sid').AsString
永久字段对象的访问:QuerylSid.DisplayLabel:=学生编号’
Query1Sid.DisplayWidth:=12
五、对数据库表数据的操作方法
(1)访问表中某一字段的数据的方法:
?Table1.FieldByName('bookidx').AsString
?Tablel.Field[O].AsInteger
?Tablel.Fieldvaluesf'bookidx'l
(2)数据库表的一些属性:
?当前记录号:Table1.Recno
?记录总数:Table1.RecordCount
?得到表的字段名:TableLGetFiekiNames(ListBoxloItems)
(3)数据维护的方法:
?Edit方法:把数据集设置为编辑状态;
?Append方法:把数据集设置为插入状态(最后);
?Insert方法:把数据集设置为插入状态(当前记录后);
?Post方法:把修改的记录写回数据集;
?Cancel方法:取消当前的操作;
?Delete方法:删除表中当前记录;
?AppendRecord方法:
?InsertRecord方法:tablel.InsertRecord(『963409',NIL,NIL,'考试']);
?SetRecords方法:
?Abort方法:取消各种方法的调用;
(4)输入数据的合法性验证
对数据库表建立合法性验证机制(如在DBD设置表的ValidityCheck、TableLookup>
ReferentialIntegrity等属性);
?在字段编辑表FieldsEditor(双击Ttable对象),选择字段,编写其OnValidate事件,要求
非空可.设置其Required属性为True;
?在程序中防止不合法输入(如:使用TDBcombobox对象,TDBlookupcombobox对象);
六、数据检索
(1)利用索引排序
如:TABLEI.IndexName:="uspa'或TABLEI.IndexFieldNames:='user_id'
(2)使用GotoKey方法查找数据库中的记录
?要求查找字段建立了索弓I,非主索引要设置Ttable对象的IndexName属性。
?调用SetKey方法,把要查找的Ttable对象置成查找模块;
?把查找值送进被查找的Field的查找缓冲区;
?调用Ttable对象的GotoKey方法,测试该方法的返回值判断查找是否成功;
(3)使用FindKey方法查找数据库中的记录
把查找值作为参数传递给FindKey函数,允许有多个查找值,要求把要查找的多个字段的
索引名赋给Ttable对象的IndexName属性;
(4)不精确查找
GotoNearest方法
FindNearest方法
(5)使用Locate方法查找数据库中的记录(不用建索引)
table1.locale('字段名1;字段名2',VarArroyof(「值1',,值2']),[LoCaselnsensitive,
LoPartialKey])
LoCaselnsensitive:忽略大小写;loPartialKey:不精确查找
(6)设定查找范围的方法
SetRangeStart>SetRangeEnd、EditRangeStart、EditRangeEnd、SetRange([StartValues],[End
Value])>ApplyRange、CancelRange
(7)用TQuery组件的动态SQL语句进行查找
七、修改数据库中的记录
在程序中对数据库记录进行操作可按下列的步骤进行:
(1)移动数据指针到要修改的记录;
(2)调用Edit方法将Ttable组件设置成编辑状态;
(3)修改字段值;(Tablel.Fieldvalues「字段名']:=值、TableLField[O].AsString:=值)
(4)可用Nil对字段赋空值;
(5)调用Post方法将修改后的记录写入数据库;
八、插入和删除记录
删除:移动指针到相应记录处,调用Delete方法;
插入:调用Insert,InsertRecord方法(当前记录处插入)或Append、InsertRecord方法(表
的末尾插入);
2003-11-2510:11:12动态的添加PARADOX表的方法【王寒松】下面给出的函数
AddMasterPassword完成添加PARADOX表主口令的工作
AddMasterPassword(Table1,'MyNewPassword')
procedureAddMasterPassword(Table:Tlable;pswd:string);
const
RESTRUCTURE_TRUE=WordBool(l);
var
TblDesc:CRTblDesc;
hDb:hDBIDb;
begin
{表打开?表是独占吗?}
if(Table.Active=False)or(Table.Exclusive=False)then
raiseEDatabaseError.CreateC数据表必须在独占方式才可以添加口令');
{初始化表描述区}
FillChar(TblDesc,SizeOf(CRTblDesc),0);
withTblDescdo
begin
{把表名放到描述区}
StrPCopy(szTblName,Table.TableName);
{把表类型放到描述区}
StrCopy(szTblType,szPARADOX);
StrPCopy(szPassword,pswd);
{设置BPROTECTED为TRUE}
bProtected:=RESTRUCTURE_TRUE;
end;
{从当前的HANDLE里得至ljDATABASE的HANDLE}
Check(DbiGetObjFromObj(hDBIObj(Table.Handle),objDATABASE,hDBIObj(hDb)));
{关闭表}
Table.Close;
{添加主口令到PARADOX表里}
Check(DbiDoRestructure(hDb,1,@TblDesc,nil,nil,nil,FALSE));
{添加一个新口令到SESSION}
Session.AddPassword(pswd);
{重新打开表}
Table.Open;
end;
添加副口令的办法与此类似
2003-11-2511:21:29如何选择一个好的数据库【三大数据库比较】
【开放性】
SQLServer
只能在windows上运行,没有丝毫的开放性,操作系统的系统的稳定对数据库是十分重
要的。Windows9X系列产品是偏重于桌面应用,NTserver只适合中小型企业。而且windows
平台的可靠性,安全性和伸缩性是非常有限的。它不象unix那样久经考验,尤其是在处理
大数据量的关键业务时.
Oracle
能在所有主流平台上运行(包括windows)o完全支持所有的工业标准。采用完全开放策
略。可以使客户选择最适合的解决方案。对开发商全力支持。
DB2
能在所有主流平台上运行(包括windows)o最适于海量数据。DB2在企业级的应用最为
广泛,在全球的500家最大的企业中JL乎85%以上用DB2数据库服务器,而国内到97年约占
5%.
【可伸缩性,并行性】
SQLserver
并行实施和共存模型并不成熟。很难处理日益增多的用户数和数据卷。伸缩性有限。
Oracle
平行服务器通过使一组结点共享同一簇中的工作来扩展windownt的能力,提供高可用性和
高伸缩性的簇的解决方案。如果WindowsNT不能满足需要,用户可以把数据库移到UNIX
中。
DB2
DB2具有很好的并行性。DB2把数据库管理扩充到了并行的、多节点的环境.数据库分区
是数据库的一部分,包含自己的数据、索引、配置文件、和事务日志。数据库分区有时被称
为节点或数据库节点
【安全性】
SQLserver
没有获得任何安全证书。
OracleServer
获得最高认证级别的ISO标准认证。
DB2
获得最高认证级别的ISO标准认证。
【性能】
SQLServer
多用户时性能不佳
Oracle
性能最高,保持WindowsNT下的TPC-D和TPC-C的世界记录。
DB2
适用于数据仓库和在线事物处理,性能较高。
【客户端支持及应用模式】
SQLServer
C/S结构,只支持windows客户,可以用ADO,DAO,OLEDB,ODBC连接.
Oracle
多层次网络计算,支持多种工业标准,可以用ODBC,JDBC,OCI等网络客户连接
DB2
跨平台,多层结构,支持ODBC,JDBC等客户
【操作简便】
SQLServer
操作简单,但只有图形界面.
Oracle
较复杂,同时提供GUI和命令行,在WindowsNT和unix下操作相同
DB2
操作简单,同时提供GUI和命令行,在WindowsNT和unix下操作相同
【使用风险】
SQLserver
完全重写的代码,经历了长期的测试,不断延迟,许多功能需要时间来证明。并不十分兼
容早期产品。使用需要冒一定风险。
Oracle
长时间的开发经验,完全向下兼容。得到广泛的应用。完全没有风险。
DB2
在巨型企业得到广泛的应用,向下兼容性好。风险小。
2003-11-2511:25:37SQL查询语句使用一、简单查询
简单的Transact-SQL查询只包括选择列表、FROM子句和WHERE子句。它们分别说明所
查询列、查询的表或视图、以及搜索条件等。
例如,卜.面的语句查询testtable表中姓名为“张三”的nickname字段和email字段。
SELECTnickname,email
FROMtesttable
WHEREname='张三'
(一•)选择列表
选择列表(select」ist)指包所查询列,它可以是一组列名列表、星号、表达式、变量(包括局
部变量和全局变量)等构成。
1、选择所有列
例如,下面语句显示testtable表中所有列的数据:
SELECT*
FROMtesttable
2、选择部分列并指定它们的显示次序
查询结果集合中数据的排列顺序与选择列表中所指定的列名排列顺序相同。
例如:
SELECTnickname,email
FROMtesttable
3、更改列标题
在选择列表中,可重新指定列标题。定义格式为:
列标题=列名
列名列标题
如果指定的列标题不是标准的标识符格式时,应使用引号定界符,例如,下列语句使用汉
字显示列标题:
SELECT昵称=nickname,电子邮V^email
FROMtesttable
4、删除重复行
SELECT语句中使用ALL或DISTINCT选项来显示表中符合条件的所有行或删除其中重
复的数据行,默认为ALL。使用DISTINCT选项时,对于所有重复的数据行在SELECT返
回的结果集合中只保留一行。
5、限制返回的行数
使用TOPn[PERCENT]选项限制返回的数据行数,TOPn说明返回n行,而TOPn
PERCENT时,说明n是表示一百分数,指定返回的行数等于总行数的百分之几。
例如:
SELECTTOP2*
FROMtesttable
SELECTTOP20PERCENT*
FROMtesttable
(-)FROM子句
FROM子句指定SELECT语句查询及与查询相关的表或视图。在FROM子句中最多可指
定256个表或视图,它们之间用逗号分隔。
在FROM子句同时指定多个表或视图时,如果选择列表中存在同名列,这时应使用对象
名限定这些列所属的表或视图。例如在usertable和citytable表中同时存在cityid列,在查询
两个表中的cityid时应使用下面语句格式加以限定:
SELECTusername,citytable.cityid
FROMusertable,citytable
WHEREusertable.cityid=citytable.cityid
在FROM子句中可用以下两种格式为表或视图指定别名:
表名as别名
表名别名
例如上面语句可用表的别名格式表示为:
SELECTusername,b.cityid
FROMusertablea,citytableb
WHEREa.cityid=b.cityid
SELECT不仅能从表或视图中检索数据,它还能够从其它查询语句所返回的结果集合中查
询数据。
例如:
SELECTa.au_fname+a.au_lname
FROMauthorsa,titleauthorta
(SELECTtitleJd,title
FROMtitles
WHEREytd_sales>10000
)ASt
WHEREa.au_id=ta.au_id
ANDta.title_id=t.title_id
此例中,将SELECT返回的结果集合给予一别名t,然后再从中检索数据。
(三)使用WHERE子句设置查询条件
WHERE子句设置查询条件,过滤掉不需要的数据行。例如下面语句查询年龄大于20的
数据:
SELECT*
FROMusertable
WHEREage>20
WHERE子句可包括各种条件运算符:
比较运算符(大小比较):>、>=、=、<、<=、<>、!>、!<
范围运算符(表达式值是否在指定的范围):BETWEEN...AND...
NOTBETWEEN...AND...
列表运算符(判断表达式是否为列表中的指定项):IN(项1,项2……)
NOTIN(项1,项2.......)
模式匹配符(判断值是否与指定的字符通配格式相符):LIKE、NOTLIKE
空值判断符(判断表达式是否为空):ISNULL、NOTISNULL
逻辑运算符(用于多条件的逻辑连接):NOT,AND、OR
1、范围运算符例:ageBETWEEN10AND30相当于age>=10ANDagev=30
2^列表运算符例:countryIN('Germany','China')
3、模式匹配符例:常用于模糊查找,它判断列值是否与指定的字符串格式相匹配。可用
于char、varchar、text>ntext、datetime和smalldatetime等类型查询。
可使用以下通配字符:
百分号%:可匹配任意类型和长度的字符,如果是中文,请使用两个百分号即%%。
下划线二匹配单个任意字符,它常用来限制表达式的字符长度。
方括号口:指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。
ri:其取值也口相同,但它要求所匹配对象为指定字符以外的任•个字符。
例如:
限制以Publishing结尾,使用LIKE%Publishing'
限制以A开头:LIKE'[A]%,
限制以A开头外:LIKE'[AA]%'
4、空值判断符例WHEREageISNULL
5、逻辑运算符:优先级为NOT、AND、OR
(四)查询结果排序
使用ORDERBY子句对查询返回的结果按洌或多列排序。ORDERBY子句的语法格式
为:
ORDERBY{column_name[ASCIDESCJ}
其中ASC表示升序,为默认值,DESC为降序。ORDERBY不能按ntext,text和image
数据类型进行排序。
例如:
SELECT*
FROMusertable
ORDERBYagedesc,useridASC
另外,可以根据表达式进行排序。
二、联合查询
UNION运算符可以将两个或两个以上上SELECT语句的查询结果集合合并成一个结果集
合显示,即执行联合查询。UNION的语法格式为:
select_statement
UNION[ALL]selectstatement
[UNION[ALLJselectstatement][...nJ
其中selectstatement为待联合的SELECT查询语句。
ALL选项表示将所有行合并到结果集合中。不指定该项时,被联合查询结果集合中的重复
行将只保留一行。
联合查询时,查询结果的列标题为第一个查询语句的列标题。因此,要定义列标题必须在
第一个查询语句中定义。要对联合查询结果排序时,也必须使用第一查询语句中的列名、列
标题或者列序号。
在使用UNION运算符时,应保证每个联合查询语句的选择列表中有相同数量的表达式,
并且每个查询选择表达式应具有相同的数据类型,或是可以自动将它们转换为相同的数据类
型。在自动转换时,对于数值类型,系统将低精度的数据类型转换为高精度的数据类型。
在包括多个查询的UNION语句中,其执行顺序是自左至右,使用括号可以改变这--执行
顺序。例如:
查询1UNION(查询2UNION查询3)
三、连接查询
通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于
其它类型数据库管理系统的一个标志。
在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信
息存放在一个表中。当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。
连接操作给用户带来很大的灵活性,他们可以在任何时候增加新的数据类型。为不同实体创
建新的表,尔后通过连接进行查询。
连接可以在SELECT语句的FROM子句或WHERE子句中建立,似是而非在FROM子句
中指出连接时有助于将连接操作与WHERE子句中的搜索条件区分开来。所以,在
Transact-SQL中推荐使用这种方法。
SQL-92标准所定义的FROM子句的连接语法格式为:
FROMjoin_tablejoin_typejoin_table
[ON(join_condition)]
其中join_table指出参与连接操作的表名,连接可以对同一个表操作,也可以对多表操作,
对同一个表操作的连接又称做自连接。
join_type指出连接类型,可分为三种:内连接、外连接和交叉连接。内连接(INNERJOIN)
使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数
据行。根据所使用的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。
外连接分为左外连接(LEFTOUTERJOIN或LEFTJOIN)、右外连接(RIGHTOUTERJOIN
或RIGHTJOIN)和全外连接(FULLOUTERJOIN或FULLJOIN)三种。与内连接不同的是,
外连接不只列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或
两个表(全外连接时)中所有符合搜索条件的数据行。
交叉连接(CROSSJOIN)没有WHERE子句,它返回连接表中所有数据行的笛卡尔积,其
结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询
条件的数据行数。
连接操作中的ON(join_condition)子句指出连接条件,它山被连接表中的列和比较运算
符、逻辑运算符等构成。
无论哪种连接都不能对text、ntext和image数据类型列进行直接连接,但可以对这三种列
进行间接连接。例如:
SELECTp1,pub_id,p2.pub_id,p1.pr_info
FROMpubjnfoASplINNERJOINpubjnfoASp2
ONDATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)
(一)内连接
内连接查询操作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值。
内连接分三种:
1、等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列
出被连接表中的所有列,包括其中的重复列。
2、不等连接:在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列
值。这些运算符包括>、>=^<=>V、!>、!v和o。
3、自然连接:在连接条件中使用等于(二)运算符比较被连接列的列值,但它使用选择列表
指出查询结果集合中所包括的列,并删除连接表中的重复列。
例,下面使用等值连接列Hlauthors和publishers衣中位于同,城市的作者和出।版社:
SELECT*
FROMauthorsASaINNERJOINpublishersASp
ONa.city=p.city
又如使用自然连接,在选择列表中删除authors和publishers表中重复列(city和state):
SELECTa.*,p.pub_id,p.pub_name,p.country
FROMauthorsASaINNERJOINpublishersASp
ONa.city=p.city
(二)外连接
内连接时,返回查询结果集合中的仅是符合查询条件(WHERE搜索条件或HAVING条
件)和连接条件的行。而采用外连接时,它返回到查询结果集合中的不仅包含符合连接条件
的行,而且还包括左表(左外连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数
据行。
如下面使用左外连接将论坛内容和作者信息连接起来:
SELECTFROMluntanLEFTJOINusertableasb
ONa.username=b.usemame
下面使用全外连接将city表中的所有作者以及user表中的所有作者,以及他们所在的城市:
SELECT
FROMcityasaFULLOUTERJOINuserasb
ONa.username=b.usemame
(三)交叉连接
交叉连接不带WHERE子句,它返回被连接的两个表所有数据行的笛卡尔积,返回到结
果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条
件的数据行数。
例,titles表中有6类图书,而publishers表中有8家出版社,则下列交叉连接检索到的记
录数将等于6*8=48行。
SELECTtype,pub_name
FROMtitlesCROSSJOINpublishers
ORDERBYtype
2003-11-2511:31:30SQLServer中ImageDataType的使用技巧【国商网络有限公司蒋心
武】MSSQLServer是微软公司推出的大型数据库软件,在NT平台上拥有近一半的数据
库市场,特别是在SQLServer7。推出后,其发展势头更加迅猛。SQLServer中Image数据
类型是用来存储图形的。在此我谈谈怎样增、册k改此类型数据及在主页中读出此类型数据。
一、在表中添加图形
Image数据类型不同于其它数据类型,不能用Insert、Update的标准SQL语法进行图形
的添加和修改。需用到SQLServer中的TEXTPTR、WRITETEXT、UPDATETEXT等函数
进行图形的添加和修改。
首先假设在库Im_Test中建立一张表此表中有两个字段,分别为Pr_Id(INT),
Prjnfo(IMAGE),用来存储图形编号及图形信息。其语法如下:
CREATETEALEImjnfo(
PjIdINTNULL,
PrjnfoIMAGENULL
第一步往表中插入一条记录,并初始化PR」NFO字段。其语法如下:
INSERTINTOIm_InfoVALUES(1,OxFFFFFFFF)
第二步往表中写入图形信息。其语法如下:
DECLARE@@ptrvalvarbinary(16)
SELECT@@ptrval=TEXTPTR(PrJnfo)
FROMIm」nfo
WHEREPr_Id=1
WRITETEXTIm_Text.Im_Info
@@ptrval0x624fd543fd..
其中0x624fd543fd..…为图形的十六进制数据,可以通过C.Java等工具获得。注意在
写入图形信息前必须先将此数据库的‘selectinto/bulkcopy,属性设置为True,其语法如下:
sp_dboptionIm_Test,
'selectinto/bulkcopy*,True
若想修改图形数据可用UPDATETEXT函数修改,其语法如下:
DECLARE@@ptrvalvarbinary(16)
SELECT@@ptrval=TEXTPTR(Pr_Info)
FROMIm_Info
WHEREPrjd=1
UPDATETEXTIm_Text.Im_Info
@@ptrval0xaa31bcfe543fd.....
二、在主页中显示图形
第一步建立数据源
若想将加入的图形显示在主页中,必须先建立数据源,打开Windows中的控制面板。通
过ODBC应用程序,建立数据源(取名Im_Test)连接到Im_Test数据库
第二步编写程序
<%@LANGUAGE=VBScript%>
<%OptionExplicit%>
<%
DimoConn
DimoRs
DimPic
DimPicSize
Response.Buffer=TRUE
Response.ContentType="image/gif
SetoConn=Server.CreateObject("ADODB.Connection1')
oConn.Open
SetoRs=oConn.Execute("SELECTPrjnfoFROMIm_InfoWHEREPr_Id=T,)
PicSize=oRs(nPr_Info").ActualSize
Pic=oRsC'PrJnfon).GetChunk(PicSize)
Response.BinaryWritePic
Response.End
%>
此程序中先定义四个变量。然后设置属性Response.Buffer=TRU和Response.ContentType=
“image/gif”,再连接数据库取出图形,在加以显示。
2003-11-2511:41:44深入SQL编程【关于存储过程和索引】这里所指的SQL编程并
不是那些在象ASP,PHP脚本语言里用的某个SQL语句,如果你是个程序员并在做DBC/S
开发,我想你会很清楚的知道SQL编程是很复杂的,先抛开嵌入语句,动态执行,高级函
数,表达试等这些不谈单就解决性能问题就很头疼,下面就性能问题给出一些解决放案.(以
下程序均在NT+SP6SQLSERVER7下调试通过)
一,存储过程
我的一个朋友用VC/SQLSERVER做C/S项目开发,再开发过程中他的程序虽顺利执行,
但遇到了由于需要大批量插入数据而引出的性能问题。他找到了我,虽然我没有用过VCHH
很明显在他程序中看出是在前台用循环操作象后台插入数据。这种方法再处理大批量数时无
疑是不可取的,因编译器并不会处理SQL语句而是通过ODBC传输到后台,再在后台解释
执行。
由此可见经过以上几步性能问题以大打折扣,后我将他的程序段改为后台SQL编程,用
存储过程实现。然后在前台用VC调用,这样一来问题以得到完美的解决。改后程序如下:
(遇到此类问题的朋友可参考解决)
CREATEPROCusp_insert_temp
@iCountVARCHAR(10),
@TextVARCHAR(50),
©priceVARCHAR(15)
AS
DECLARE@ilndexINT
DECLARE@pMoneyFLOAT
SET@iIndex=CONVERT(INT,@iCount)
SET@pMoney=CONVERT(FLOAT,©price)
BEGINTRAN
SELECTrygl_id,title,price
INTOrygl_tempFROMrqk
WHEREEXISTS
(SELECTrygl_id
FROMrygl
WHERErqk.rygl_id=rygl.rygl_id
ANDqty<30)
ORDERBYtitlejd
IF@@ERROR<>0
ROLLBACKTRAN
ELSE
COMMITTRAN
WHILE@iIndex>0
BEGIN
BEGINTRAN
SET@pMoney=@pMoney+1.1111
INSERTINTOrygl_temp(rygl_id,title,price)
VALUES(@ilndex,@Text,CONVERT(SMALLMONEY,@pMoney))
IF@@ERRORoOOR@@ROWCOUNT=0
ROLLBACKTRAN
ELSE
COMMITTRAN
SET@ilndex=@ilndex-1
END
二,索引测试,比较
合理的索引建立,运用可很大幅度提高程序性能,以下是在工作当中得出的经验,与大家
共享。
1.ORDERBY和GROPUBY
如果用户经常选择数据和使用ORDERBY和GROUPBY短语,任何一种索引都有助于
SELECT的性能提高。如果用户选择的是顾客并按其姓名分类,两种索引都能快速检索数据。
但下面的一些因素会使用户选择使用某一种索引。
2,返回范围内的数据
列如,如果拥护希望返回在SMITH和TALBERT之间的所有顾客姓名,或者返回在日期
“11/1/98”和T1/30/98”之间的订货量,并且用户经常做这类事情,那么最好在该范围所在的
指定列使用聚类索引。因聚类索引已包含了经过分类排序的数据,这对于在指定范围内检索
数据更为有效。聚类索引只需找到要检索的所有数据中的开头和结尾数据即可;而不象非聚
类索,必须在数据层专查找来字叶层的每一个数据项。
3,列中有一个或极少的不同值
在用户表中的某些列中喊有极少不同值,列如状态列中只包含INACVTIVE,ACVIVE或
者TERMINATED。在这种情况下,在该列上使用任何类型索引都是不明智的,原因很简单:
如果用户表包含了1500行大概有三分之一的行即500行在状态列中含有ACTIVE。扫描整
个表,如果不是更高效,至少也是同先在索引页面中查找每个数据项而后寻找到包含
ACTIVE状态的行所在的数
据页面也相同的效率。下面这个列子创建了一个表,它在有很很多重复值的列上进行索弓I,
而该列具有很少的不同值。运行该脚本可能要花几分钟。
*/
DROPTABLEIndexTestTable
CREATETABLEIndexTestTable
(
TidINTIDENTITY(IJ)NOTNULL,
StatusCHAR(10)NULL
)
GO
SETIDENTITY_INSERTIndexTestTableON
DECLARE@intCountINT
BEGINTRAN
SET@intCount=l
WHILE@intCount<=1500
BEGIN
INSERTIndexTestTable(Tid,Status)VALUES(@intCount,Active1)
SET@intCount=@intCount+3
END
SET@intCount=2
WHILE@intCount<=1500
BEGIN
INSERTIndexTestTable(Tid,Status)VALUES(@intCount,•inactive1)
SET@intCount=@intCount+3
END
SET@intCount=3
WHILE@intCount<=1500
BEGIN
INSERTIndexTestTable(Tid,Status)VALUES(@intCount,Terminated')
SET@intCount=@intCount+3
END
COMMITTRAN
SETIDENTITYJNSERTIndexTestTableOFF
GO
DUMPTRANSACTIONpubsWITHNO_LOG
GO
CREATEINDEXinTableUniquesStatus
ONIndexTestTable(Status)
GO
-不用索引查询
SELECT*
FROMIndexTestTableWITH(index(O))
WHEREStatus='inactive'
-用索引查询
SELECT*
FROMIndexTestTableWITH(index(inTableUniquesStatus))
WHEREStatus=,inactive,
选中SHOWSTATSI/O查看运行结果会另人吃惊。第一个SELECT语句引起全表扫描几乎
不需要内存操作(因为只是进行插入,所有所有数据都在内存中,并不需要进行磁盘或物理
读操作)。第二个SELECT语句则需要执行500个读操作,这就证实了我们所说的在这种情况
下,使用任何类型索引都是不明智的。
4,
以上举列说明了在何种情况下不应使用索引,现在咱们再反过来看看当索引列中
不同数目值增加时即有较少不同值时会怎样?见如下代码
*/
DROPTABLEIndexTestTable
GO
CREATETABLEIndexTestTable
(
TidINTIDENTITY(IJ)NOTNULL,
StatusCHAR(IO)NULL,
Co3CHAR(20)NOTNULL,
Co4CHAR(50)NOTNULL
)
GO
DECLARE@intNumINT
SET@intNum=0
BEGINTRAN
WHILE@intNum<=1300
BEGIN
INSERTIndexTestTable
VALUES(CHAR(@intNum%26+65);test3Vtest4')
SET@intNum=@intNum+1
END
COMMITTRAN
GO
--不用索引查询
SELECT*FROMIndexTestTableWHIT(INDEX(O))
WHEREStatus^B1
--创建聚集索引
CREATECLUSTEREDINDEXicIndexTestTable
ONIndexTestTable(Status)
GO
-使用索引查询
SELECT*FROMIndexTestTableWITH(INDEX(icIndexTestTable))
WHEREStatus=B
5,
用户很明显地能看出,随着表中行的数目和列中不同值的增长。使用索引可以较大幅度提
高效率,由此又引出另一个问题,在何种情况下用何种索引更有效?上面列子一经介绍了聚
类索引,大家都能看出在对于有较少不同植时使用聚类索引是有很大帮助的,但当不同值的
数木增加并达到表中行的树木时则应该选非聚类索弓I。此时使用非聚类索在读操作上和聚类
似索引并无
二异,但在对表进行写操作上的性能却提高不少,如果用户经常从表中的一个或少是数几个
字段中检索数据,当非聚集索引包含要检索的所有字段时就会减少所需的读操作,如果不是
那么正如上面第二条所说使用非聚集索引通常是钟很差的选择,下面这个列子说明了在何时
应该使用聚集索引
*/
DROPTABLEIndexTestTable
GO
CREATETABLEIndexTestTable
(
TidINTIDENTITY(1,1)NOTNULL,
StatusCHAR(20)NOTNULL
)
GO
DECLARE@intCountINT
SET@intCount=0
BEGINTRAN
WHILE@intCount<=500
BEGIN
INSERTINTOIndexTestTable(Status)VALUES('test'+CONVERT(CHAR(6),@intCount))
SET@intCount=@intCount+1
END
COMMITTRAN
GO
-创建聚集索引
CREATECLUSTEREDINDEXicIndexTestTable
ONIndexTestTable(Tid)
GO
―创建非聚集索引
CREATEINDEXinlndexTestTable
ONIndexTestTable(Tid)
GO
-使用非聚集索引查询
SELECTTidFROMIndexTestTableWITH(INDEX(inIndexTestTable))
WHERETidBETWEEN100AND500
-使用聚集索引查询
SELECTTidFROMIndexTestTableWITH(INDEX(icIndexTestTable))
WHERETidBETWEEN100AND500
集索引包含绝大多数的检索数据,则只需要读取很少的数据页这种情况下非聚集索引要比
聚集索引好,如果表的数据行很庞大效果会更加明显。
6,
要说明的是,索引虽有助于提高性能但不是索引越多越好,恰好相反过多的索引会导致系
统低效。用户在表中每加进一个索引,维护索引集合就要做相应的更新工作。
2003-11-2511:49:45SQLServer日期计算通常,你需要获得当前日期和计算一些其他的
II期,例如,你的程序可能需要判断一个月的第一天或者最后一天。你们大部分人大概都知
道怎样把日期进行分割(年、月、日等),然后仅仅用分割出来的年、月、日等放在几个函
数中计算出自己所需要的口期!在这篇文章里,我将告诉你如何使用DATEADD和
DATEDIFF函数来计算出在你的程序中可能你要用到的一些不同日期。
在使用本文中的例子之前,你必须注意以下的问题。大部分可能不是所有例子在不同的机器
上执行的结果可能不一样,这完全由哪一天是一个星期的第一天这个设置决定。第一天
(DM'EFIRST)设定决定了你的系统使用哪一天作为一周的第一天。所有以下的例子都是
以星期天作为一周的第一天来建立,也就是第一天设置为7。假如你的第一天设置不一样,
你可能需要调整这些例子,使它和不同的第一天设置相符合。你可以通过@@DATEFIRST
函数来检查第一天设置。
为了理解这些例子,我们先复习一下DATEDIFF和DATEADD函数。DATEDIFF函数计
算两个日期之间的小时、天、周、月、年等时间间隔总数。DATEADD函数计算一个口期通
过给时间间隔加减来获得一个新的日期。要了解更多的DATEDIFF和DAT
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 旅游企业会计课程设计
- 小班篮球拍球课程设计
- 幼儿园小溪语言课程设计
- 无意识写作课程设计理念
- 幼儿园花生制作课程设计
- 服装工程管理课程设计
- 桥梁维保技术服务合同
- 大班劳动挑战课程设计
- 2024年二零二四年度水路货物运输合同船舶排放污染物处理协议3篇
- 玩具行业购销合同示例
- 碧桂园营销标准化工作集群与监控节点清单
- SoftMaster使用说明
- 医疗器械员工培训记录
- 中国船舶发展史
- 危险废物的培训总结
- 浙江省公路水运工程工地试验室管理暂行办法
- 国家开放大学电大《管理英语4》形考任务5试题及答案
- 六类网线检测报告(共9页)
- 安徽中电龙子湖工业园区12MW光伏发电示范项目二工区设备采购第一批35kV箱式变电站技术协议
- 注塑换模作业指导书
- 国家住宅装饰装修工程施工规范标准
评论
0/150
提交评论