实验三sql查询语句(共7篇)
(子查询、分组查询)
一、实验目的
使用SQL语言完成数据定义、数据查询、数据更新等功能。
二、实验要求
1.掌握使用SQL定义、删除和修改基本表。2.掌握使用SQL完成单表查询、多表查询。3.掌握连接查询和嵌套查询。
4.掌握使用SQL完成数据插入、数据修改、数据删除等功能。
三、实验内容
在“FLY飞翔公司数据库”数据库中,完成以下SQL查询实验。(以下的SQL查询实验可能会多种SQL命令描述方式,建议同学多思考、多尝试)
实验1 使用SQL命令,查询公司机构C1和C2中基本工资低于3000的员工信息。
提示:使用两个IN函数,其中一个IN函数是IN(“C1”, “C2”),另外一个IN函数是嵌套SELECT语句
实验2使用SQL命令,查询公司机构C1和C2中基本工资低于3000的员工信息。
实验3使用SQL命令,查询显示基本工资大于2000,且不超过3000元的员工编号及其所在公司名称。
实验4使用SQL命令,查询显示查询供应商“兆海公司”未供应的商品类型名称。提示:使用NOT IN 函数实现
实验5使用SQL命令,查询显示员工的姓名,所属公司名称和工资收入(工资收入=基本工资+任务工资+奖金-住房公积金-扣款)。提示:产生新字段要使用As
实验6使用SQL命令,分组统计供应了商品的供应商所提供的商品种类数量,显示供应商名称和商品种类数量。提示:使用COUNT函数 实验7使用SQL命令,分组统计每笔订单的净收益,显示订单编号和金额为200到500之间的净收益。(净收益=(销售价格-购入价格)*数量*折扣)。
提示:group by是分组,having是判断,同学选做。
实验8使用SQL命令,查询与员工王芳签订过订单的零售商名称和订单编号,并将结果存在一个新表New_temp中。
提示: Select 零售商名称, 订单编号 Into New_temp 是将所选字段存入新表New_temp中。
实验9使用SQL命令,查询未与员工E3签订过订单的零售商名称和所在城市。提示:使用Not IN函数
关键词:SQL,优化策略,数据库性能,谓词
0 引言
查询是数据库中最基本、最常用、最复杂的操作。在数据库的管理信息系统中,查询操作是所有数据库操作中所占据比重最大的操作。当数据库系统积累到一定程度,若查询时采用单条顺序扫描,那么扫描一遍所有的记录可能就得花上几十分钟,甚至几小时,这样的系统就失去了现实的使用价值。采取什么样的查询策略,使查询时间降为几分钟或者几秒钟,就是这里需要研究的查询优化问题。
1 优化原理[1]
查询优化力图找出给定表达式等价,但执行效率更高的一个表达式,一个查询往往会有许多实现方法,关键是如何找出一个与之等价的且操作时间又少的表达式,查询优化关注的问题是怎样省时、省空间以及效率高。优化的核心问题是尽可能减少查询中各表的参与加工的数据量,从而达到优化时间和空间的目的。
2 SQL优化的方法
2.1 模糊匹配的避免
LIKE关键字支持通配符匹配,技术上称为正则表达式。但这种匹配特别耗费时间,尽量避免使用模糊匹配。例:
即使在rx score字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。
可改写为:
这样,在执行查询时就会利用索引来查询,显然会大大提高速度。
2.2 逻辑表达式的等价变换
由于执行引擎对各种谓词的处理方法不同,因此把逻辑表达式重写成等价的且效率较高的表达式是提高查询效率的有效方法,同时也是切实可行的[2]。通过查阅大量的文献资料以及大量的实验,分析了RDBMS执行引擎对各种谓词执行效率的不同,总结出以下几种逻辑表达式转换规则:
2.2.1 将多个OR连接的表达式转化为ANY表达式
当条件表达式中同层次上出现由连接词OR连接的表达式,并且OR所连接的表达式的左表达式相同且谓词符号也相同时,那么可以将这些表达式合并为一个右表达式用ANY来描述的表达式。例:
可改写为:
2.2.2 将ANY或ALL转化为简单的比较表达式
当谓词的右表达式为ANY或ALL的形式,并且ANY(ALL)包含的各表达式均有固定值,并且可以比较大小,则可根据谓词符号(仅限于比较大小的操作符)将ANY(ALL)重写为简单的比较表达式。例:
x>ANY(100,200,300) 可改写为:x>100;
x>ALL(100,200,300) 可改写为:x>300
2.2.3 将BETWEEN…AND转化为AND连接的表达式
可以把由BETWEEN expr1 AND expr2的形式重写为用AND连接的两个表达式,效率往往有一定的提高。例:
可改写为:
2.2.4 将IN谓词表达式转换为OR连接的谓词表达式
例:年龄IN(20,30,40)
可写为:年龄=20 OR年龄=30 OR年龄=40
以上提到的4类谓词重写规则均有其特定的条件,在条件满足的情况下才可以使用。对于简单谓词的重写,每条规则提高的效率可能不太明显,但如果查询语句的WHERE条件同时使用多条规则进行重写时,效率的提高将非常可观。
2.3 子查询合并
子查询合并是将某些特定的子查询重写为等价的多个表的连接操作。子查询合并的作用在于能使查询语句的层次尽可能地减少,从而可提高查询的效率。子查询合并的一般规则为:
(1)如果外层查询的结果没有重复,即SELECT子句中包含主码,则可以合并其子查询,并且合并后的SELECT子句前应加上DISTINCT标志;
(2)如果外层查询的SELECT子句中有DISTINCT标志,那么可以直接进行子查询合并;
(3)如果内部子查询结果没有重复元组,则可以合并。
例:查询选修002号课程的学生基本信息。
用子查询的方法如下所示,例:
可改写为:
2.4 用集合运算来代替逻辑运算
0R在嵌套查询中,表的顺序存取对查询效率可能产生致命的影响,避免这种情况的方法就是对连接的列进行索引。例如两个表:student(sno,sname,age)和sc(sno,cno,score)。如果两个表要做连接,就要在“sno”这个连接字段上建立索引。还可以使用并集来避免顺序存取,尽管在所有检查列上都有索引,但某些形式的WHERE子句强迫优化器使用顺序存取。下面的查询将强迫对student表执行顺序操作:
OR xb=′计算机系′
虽然在sno和系别名上都建有索引,但是在上面的语句中优化器还是使用顺序存取的方法扫描整个表因为这个语句要检索的是分离的行的集合,所以应该改为如下语句:
UNION SELECT*FROM student WHERE xb=′计算机系′
2.5 多表连接优化
最能体现查询复杂性的就是多表连接,多表连接操作往往要耗费大量的CPU时间和内存,因此多表连接查询性能优化往往是SQL优化的重点与难点[3]。
2.5.1 充分利用连接条件
在某种情况下,两个表之间可能不只一个的连接条件,这时在WHERE子句中将连接条件完整的写上,有可能大大提高查询速度。例:
这里,第二句将比第一句执行快得多。
2.5.2 先筛选后连接
当查询多个数据表时,要先过滤后再连接。例:
它们的执行效率相差很大。第一个查询语句首先将两个数据表按照用户ID进行连接,然后再将符合条件的记录筛选。由于两个数据表进行连接时记录有些是以后还要筛选掉的,这显然会占用更多的时间,且多个数据表连接是笛卡儿积运算,消耗的时间会随着记录个数的增加很快地增长。第二个查询语句克服了这个缺点,首先筛选出符合条件的记录,减少了进行连接的记录个数,然后再执行连接查询,大大提高了查询效率。
3 结语
查询优化要抓住关键问题,对于数据库应用程序,重点在于如何提高SQL的执行效率。在数据库的开发和维护过程中,查询的优化设计可以提高系统性能,对于数据量大的数据库系统尤为重要。以上介绍的几种优化策略使查询在时间和空间上提高了系统的性能,在一定程度上提高了查询效率。
参考文献
[1]王珊,萨师煊.数据库系统概论[M].4版.北京:高等教育出版社,2006.
[2]丁宝康,董健全.数据库实用教程[M].2版.北京:清华大学出版社,2003.
[3]范剑波,张晓云.网络数据库技术与应用[M].西安:西安电子科技大学出版社,2004.
[4]刘志成,彭勇.数据库系统原理与应用[M].北京:机械工业出版社,2007.
[5]罗运模.SQL Server数据库系统基础[M].北京:高等教育出版社,2006.
[6]宋瀚涛,李新社.数据库编程与应用[M].北京:电子工业出版社,1998.
[7]史嘉权.数据库系统概论[M].北京:清华大学出版社,2006.
[8]马李明,王守桃,徐艳蕾.SQL语句的优化在提高数据查询中的应用[J].电脑知识与技术,2008(20):200,223.
S(Sno,Sname)
C(Cno,Cname)
SC(Sno,Cno,grade)
----------------------------------------------------
问题:
用一条SQL语句 查询出每门课都大于80分的学生姓名,
------------------------------------------------------
表如下:
SnameSnamegrade
张三语文81
张三数学75
李四语文76
李四数学90
王五语文81
王五数学100
王五英语90
---------------------------------------------------------
答案:
表test中有1000条数据,2个字段:field1(int),field2(nvarchar)
--1000条数据,查询500次第1-10行,39s
--1000条数据,查询500次第500-550行,87s
--1000条数据,查询500次第150-160行,88s
DECLARE @uId int
SET @uId=1 BEGIN while @uId<=500 BEGIN
SELECT *
FROM (
SELECT row_number() over(
ORDER BY [dbo].[test].[filed1] desc) as rownum,* from [dbo].[test]) temp
WHERE temp.rownum BETWEEN 150 AND 160;
SET @uId=@uId+1 END END;
--1000条数据,查询500次第1-10行,78s
--1000条数据,查询500次第500-550行,78s
DECLARE @uId int
SET @uId=1 BEGIN while @uId<=500 BEGIN
SELECT *
FROM [dbo].[test]
ORDER BY [dbo].[test].[filed1] DESC
OFFSET (10 * (15 - 1)) ROWS FETCH NEXT 10 ROWS ONLY
SET @uId=@uId+1 END END
测试效果:
row_Number()不稳定,考前的记录查询比较快,靠后的记录查询时间会增加
OFFSET FETCH 稳定,考前靠后的查询时间都是基本一样
1、ASCII()
返回字符表达式最左端字符的ASCII 码值。在ASCII()函数中,纯数字的字符串可不用‘’括起来,但含其它字符的字符串必须用‘’括起来使用,否则会出错。
2、CHAR()
将ASCII 码转换为字符。如果没有输入0 ~ 255 之间的ASCII 码值,CHAR()返回NULL。
3、LOWER()和UPPER()
LOWER()将字符串全部转为小写;UPPER()将字符串全部转为大写。
4、STR()
把数值型数据转换为字符型数据。
STR(
length 指定返回的字符串的长度,decimal 指定返回的小数位数。如果没有指定长度,缺省的length 值为10,decimal 缺省值为0。
当length 或者decimal 为负值时,返回NULL;
当length 小于小数点左边(包括符号位)的位数时,返回length 个*; 先服从length,再取decimal ;
当返回的字符串位数小于length,左边补足空格。
二、去空格函数
1、LTRIM()把字符串头部的空格去掉。
2、RTRIM()把字符串尾部的空格去掉。
三、取子串函数
1、left()
LEFT(
返回character_expression 左起 integer_expression 个字符。
2、RIGHT()
RIGHT(
返回character_expression 右起 integer_expression 个字符。
3、SUBSTRING()
SUBSTRING(
返回从字符串左边第starting_ position 个字符起length个字符的部分。
四、字符串比较函数
1、CHARINDEX()
返回字符串中某个指定的子串出现的开始位置。
CHARINDEX(<’substring_expression’>,
其中substring _expression 是所要查找的字符表达式,expression 可为字符串也可为列名表达式。如果没有发现子串,则返回0 值。
此函数不能用于TEXT 和IMAGE 数据类型。
2、PATINDEX()
返回字符串中某个指定的子串出现的开始位置。
PATINDEX(<’%substring _expression%’>,
与CHARINDEX 函数不同的是,PATINDEX函数的子串中可以使用通配符,且此函数可用于CHAR、VARCHAR 和TEXT 数据类型。
五、字符串操作函数
1、QUOTENAME()
返回被特定字符括起来的字符串。
QUOTENAME(<’character_expression’>[,quote_ character])其中quote_ character 标明括字符串所用的字符,缺省值为“[]”。
2、REPLICATE()
返回一个重复character_expression 指定次数的字符串。
REPLICATE(character_expression integer_expression)如果
integer_expression 值为负值,则返回NULL。
3、REVERSE()
将指定的字符串的字符排列顺序颠倒。
REVERSE(
4、REPLACE()
返回被替换了指定子串的字符串。
REPLACE(
5、SPACE()
返回一个有指定长度的空白字符串。
SPACE(
6、STUFF()
用另一子串替换字符串指定位置、长度的子串。
STUFF(
如果起始位置为负或长度值为负,或者起始位置大于
character_expression1 的长度,则返回NULL 值。
如果length 长度大于character_expression1 中 start_ position 以右的长度,则character_expression1 只保留首字符。
六、数据类型转换函数
1、CAST()
CAST(
2、CONVERT()
CONVERT(
1)data_type为SQL Server系统定义的数据类型,用户自定义的数据类型不能在此使用。
2)length用于指定数据的长度,缺省值为30。
3)把CHAR或VARCHAR类型转换为诸如INT或SAMLLINT这样的INTEGER类型、结果必须是带正号或负号的数值。
4)TEXT类型到CHAR或VARCHAR类型转换最多为8000个字符,即CHAR或VARCHAR数据类型是最大长度。
5)IMAGE类型存储的数据转换到BINARY或VARBINARY类型,最多为8000个字符。
6)把整数值转换为MONEY或SMALLMONEY类型,按定义的国家的货币单位来处理,如人民币、美元、英镑等。
7)BIT类型的转换把非零值转换为1,并仍以BIT类型存储。
8)试图转换到不同长度的数据类型,会截短转换值并在转换值后显示“+”,以标识发生了这种截断。
9)用CONVERT()函数的style 选项能以不同的格式显示日期和时间。style 是将DATATIME 和SMALLDATETIME 数据转换为字符串时所选用的由SQL Server 系统提供的转换样式编号,不同的样式编号有不同的输出格式。
七、日期函数
1、day(date_expression)
返回date_expression中的日期值
2、month(date_expression)
返回date_expression中的月份值
3、year(date_expression)
返回date_expression中的年份值
4、DATEADD()
DATEADD(
返回指定日期date 加上指定的额外日期间隔number 产生的新日期。
5、DATEDIFF()
DATEDIFF(
返回两个指定日期在datepart 方面的不同之处,即date2 超过date1的差距值,其结果值是一个带有正负号的整数值。
6、DATENAME()
DATENAME(
以字符串的形式返回日期的指定部分此部分。由datepart 来指定。
7、DATEPART()
DATEPART(
以整数值的形式返回日期的指定部分。此部分由datepart 来指定。DATEPART(dd,date)等同于DAY(date)
DATEPART(mm,date)等同于MONTH(date)
DATEPART(yy,date)等同于YEAR(date)
8、GETDATE()
以DATETIME 的缺省格式返回系统当前的日期和时间。
八、统计函数
AVG()-返回的平均价值
count()-返回的行数
first()-返回第一个值
last()-返回最后一个值
max()-返回的最大价值
min()-返回最小的价值
total()-返回的总和
九、数学函数
abs(numeric_expr)求绝对值
ceiling(numeric_expr)取大于等于指定值的最小整数 exp(float_expr)取指数
floor(numeric_expr)小于等于指定值得最大整数 pi()3.1415926.........power(numeric_expr,power)返回power次方
rand([int_expr])随机数产生器
round(numeric_expr,int_expr)安int_expr规定的精度四舍五入 sign(int_expr)根据正数,0,负数,返回+1,0,-1 sqrt(float_expr)平方根
十、系统函数
suser_name()用户登录名
user_name()用户在数据库中的名字 user用户在数据库中的名字 show_role()对当前用户起作用的规则
db_name()数据库名object_name(obj_id)数据库对象名
col_name(obj_id,col_id)列名
col_length(objname,colname)列长度
sql语句高效性
在SQL Server数据库中,我们在写查询语句时,一定要遵循一定的原则才能能够使SQL语句执行起来更加的高效率。本文我们主要就总结了34条写高性能SQL语句的原则,接下来就让我们一起来了解一下这部分内容吧。 (1)选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表drivingtable)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询,那就需要选择交叉表(intersectiontable)作为基础表,交叉表是指那个被其他表所引用的表. (2)WHERE子句中的连接顺序.: ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾. (3)SELECT子句中避免使用‘*‘: ORACLE在解析的过程中,会将*依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间 (4)减少访问数据库的次数: ORACLE在内部执行了许多工作:解析SQL语句,估算索引的利用率,绑定变量,读数据块等; (5)在SQL*Plus,SQL*Forms和Pro*C中重新设置ARRAYSIZE参数,可以增加每次数据库访问的检索数据量,建议值为200 (6)使用DECODE函数来减少处理时间: 使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表. (7)整合简单,无关联的数据库访问: 如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系) (8)删除重复记录: 最高效的删除重复记录方法(因为使用了ROWID)例子: 1. DELETEFROMEMPEWHEREE.ROWID>(SELECTMIN(X.ROWID) 2. FROMEMPXWHEREX.EMP_NO=E.EMP_NO); (9)用TRUNCATE替代DELETE: 当删除表中的记录时,在通常情况下,回滚段(rollbacksegments)用来存放可以被恢复的信息.如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况)而当运用TRUNCATE时,回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,执行时间也会很短.(译者按:TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML) (10)尽量多使用COMMIT: 只要有可能,在程序中尽量多使用COMMIT,这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少: COMMIT所释放的资源: a.回滚段上用于恢复数据的信息. b.被程序语句获得的锁 c.redologbuffer中的空间 d.ORACLE为管理上述3种资源中的内部花费 (11)用Where子句替换HAVING子句: 避免使用HAVING子句,HAVING只会在检索出所有记录之后才对结果集进行过滤.这个处理需要排序,总计等操作.如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销.(非oracle中)on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后,因为on是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的,where也应该比having快点的,因为它过滤数据后才进行sum,在两个表联接时才用on的,所以在一个表的时候,就剩下where跟having比较了。在这单表查询统计的情况下,如果要过滤的条件没有涉及到要计算字段,那它们的结果是一样的,只是where可以使用rushmore技术,而having就不能,在速度上后者要慢如果要涉及到计算的字段,就表示在没计算之前,这个字段的值是不确定的,根据上篇写的工作流程,where的作用时间是在计算之前就完成的,而having就是在计算后才起作用的,所以在这种情况下,两者的结果会不同。在多表联接查询时,on比where更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤,然后再计算,计算完后再由having进行过滤。由此可见,要想过滤条件起到正确的作用,首先要明白这个条件应该在什么时候起作用,然后再决定放在那里 (12)减少对表的查询: 在含有子查询的SQL语句中,要特别注意减少对表的`查询.例子: 1. SELECTTAB_NAMEFROMTABLESWHERE(TAB_NAME,DB_VER)=(SE LECT 2. TAB_NAME,DB_VERFROMTAB_COLUMNSWHEREVERSION=604) (13)通过内部函数提高SQL效率.: 复杂的SQL往往牺牲了执行效率.能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的。 (14)使用表的别名(Alias): 当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个Column上.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误. (15)用EXISTS替代IN、用NOTEXISTS替代NOTIN: 在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下,使用EXISTS(或NOTEXISTS)通常将提高查询的效率.在子查询中,NOTIN子句将执行一个内部的排序和合并.无论在哪种情况下,NOTIN都是最低效的(因为它对子查询中的表执行了一个全表遍历).为了避免使用NOTIN,我们可以把它改写成外连接(OuterJoins)或NOTEXISTS. 例子: 高效: 1. SELECT*FROMEMP(基础表)WHEREEMPNO>0ANDEXISTS 2. (SELECT‘XFROMDEPTWHEREDEPT.DEPTNO=EMP.DEPTNOANDLOC=‘MELB) 低效: 1. SELECT*FROMEMP(基础表)WHEREEMPNO>0ANDDEPTNOIN 2. (SELECTDEPTNOFROMDEPTWHERELOC=‘MELB) (16)识别低效执行的SQL语句: 虽然目前各种关于SQL优化的图形化工具层出不穷,但是写出自己的SQL工具来解决问题始终是一个最好的方法: 1. SELECTEXECUTIONS,DISK_READS,BUFFER_GETS, 2. ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2)Hit_r adio, 3. ROUND(DISK_READS/EXECUTIONS,2)Reads_per_run, 4. SQL_TEXT 5. FROMV$SQLAREA 6. WHEREEXECUTIONS>0 7. ANDBUFFER_GETS>0 8. AND(BUFFER_GETS-DISK_READS)/BUFFER_GETS<0.8 9. ORDERBY4DESC; (17)用索引提高效率: 索引是表的一个概念部分,用来提高检索数据的效率,ORACLE使用了一个复杂的自平衡B-tree结构.通常,通过索引查询数据比全表扫描要快.当ORACLE找出执行查询和Update语句的最佳路径时,ORACLE优化器将使用索引.同样在联结多个表时使用索引也可以提高效率.另一个使用索引的好处是,它提供了主键(primarykey)的唯一性验证.。那些LONG或LONGRAW数据类型,你可以索引几乎所有的列.通常,在大型表中使用索引特别有效.当然,你也会发现,在扫描小表时,使用索引同样能提高效率.虽然使用索引能得到查询效率的提高,但是我们也必须注意到它的代价.索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时,索引本身也会被修改.这意味着每条记录的INSERT,DELETE,UPDATE将为此多付出4,5次的磁盘I/O.因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢.。定期的重构索引是有必要的.: ALTERINDEX/******* 导出到excel
EXEC master..xp_cmdshell ’bcp SettleDB.dbo.shanghu out c:temp1.xls -c -q -S”GNETDATA/GNETDATA“ -U”sa“ -P”“’
/*********** 导入Excel
SELECT *
FROM OpenDataSource( ’Microsoft.Jet.OLEDB.4.0’,
’Data Source=”c:test.xls“;User ID=Admin;Password=;Extended properties=Excel 5.0’)...xactions
SELECT cast(cast(科目编号 as numeric(10,2)) as nvarchar(255))+’ ’ 转换后的别名
FROM OpenDataSource( ’Microsoft.Jet.OLEDB.4.0’,
’Data Source=”c:test.xls“;User ID=Admin;Password=;Extended properties=Excel 5.0’)...xactions
/** 导入文本文件
EXEC master..xp_cmdshell ’bcp ”dbname..tablename“ in c:DT.txt -c -Sservername -Usa -Ppassword’
/** 导出文本文件
EXEC master..xp_cmdshell ’bcp ”dbname..tablename“ out c:DT.txt -c -Sservername -Usa -Ppassword’
或
EXEC master..xp_cmdshell ’bcp ”Select * from dbname..tablename“ queryout c:DT.txt -c -Sservername -Usa -Ppassword’
导出到TXT文本,用逗号分开
exec master..xp_cmdshell ’bcp ”库名..表名“ out ”d:tt.txt“ -c -t ,-U sa -P password’
BULK INSERT 库名..表名
FROM ’c:test.txt’
WITH (
FIELDTERMINATOR = ’;’,
ROWTERMINATOR = ’n’
)
--/* dBase IV文件
select * from
OPENROWSET(’MICROSOFT.JET.OLEDB.4.0’
,’dBase IV;HDR=NO;IMEX=2;DATABASE=C:’,’select * from [客户资料4.dbf]’)
--*/
--/* dBase III文件
select * from
OPENROWSET(’MICROSOFT.JET.OLEDB.4.0’
,’dBase III;HDR=NO;IMEX=2;DATABASE=C:’,’select * from [客户资料3.dbf]’)
--*/
--/* FoxPro 数据库
select * from openrowset(’MSDASQL’,
’Driver=Microsoft Visual FoxPro Driver;SourceType=DBF;SourceDB=c:’,
’select * from [aa.DBF]’)
--*/
/**************导入DBF文件****************/
select * from openrowset(’MSDASQL’,
’Driver=Microsoft Visual FoxPro Driver;
SourceDB=e:VFP98data;
SourceType=DBF’,
’select * from customer where country != ”USA“ order by country’)
go
/***************** 导出到DBF ***************/
如果要导出数据到已经生成结构(即现存的)FOXPRO表中,可以直接用下面的SQL语句
insert into openrowset(’MSDASQL’,
’Driver=Microsoft Visual FoxPro Driver;SourceType=DBF;SourceDB=c:’,
’select * from [aa.DBF]’)
select * from 表
说明:
SourceDB=c: 指定foxpro表所在的文件夹
aa.DBF 指定foxpro表的文件名.
/*************导出到Access********************/
insert into openrowset(’Microsoft.Jet.OLEDB.4.0’,
’x:A.mdb’;’admin’;’’,A表) select * from 数据库名..B表
/*************导入Access********************/
insert into B表 selet * from openrowset(’Microsoft.Jet.OLEDB.4.0’,
’x:A.mdb’;’admin’;’’,A表)
********************* 导入 xml 文件
DECLARE @idoc int
DECLARE @doc varchar(1000)
--sample XML document
SET @doc =’
white red”>
Happy Customer.
’
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, ’/root/Customer/Order’, 1)
WITH (oid char(5),
amount float,
comment ntext ’text’)
EXEC sp_xml_removedocument @idoc
/********************导整个数据库*********************************************/
用bcp实现的存储过程
/*
实现数据导入/导出的存储过程
根据不同的参数,可以实现导入/导出整个数据库/单个表
调用示例:
--导出调用示例
----导出单个表
exec file2table ’zj’,’’,’’,’xzkh_sa..地区资料’,’c:zj.txt’,1
----导出整个数据库
exec file2table ’zj’,’’,’’,’xzkh_sa’,’C:docman’,1
--导入调用示例
----导入单个表
exec file2table ’zj’,’’,’’,’xzkh_sa..地区资料’,’c:zj.txt’,0
----导入整个数据库
exec file2table ’zj’,’’,’’,’xzkh_sa’,’C:docman’,0
*/
if exists(select 1 from sysobjects where name=’File2Table’ and objectproperty(id,’IsProcedure’)=1)
drop procedure File2Table
go
create procedure File2Table
@servername varchar(200) --服务器名
,@username varchar(200) --用户名,如果用NT验证方式,则为空’’
,@password varchar(200) --密码
,@tbname varchar(500) --数据库.dbo.表名,如果不指定:.dbo.表名,则导出数据库的所有用户表
,@filename varchar(1000) --导入/导出路径/文件名,如果@tbname参数指明是导出整个数据库,则这个参数是文件存放路径,文件名自动用表名.txt
,@isout bit --1为导出,0为导入
as
declare @sql varchar(8000)
if @tbname like ’%.%.%’ --如果指定了表名,则直接导出单个表
begin
set @sql=’bcp ’+@tbname
+case when @isout=1 then ’ out ’ else ’ in ’ end
+’ “’+@filename+’” /w’
+’ /S ’+@servername
+case when isnull(@username,’’)=’’ then ’’ else ’ /U ’+@username end
+’ /P ’+isnull(@password,’’)
exec master..xp_cmdshell @sql
end
else
begin --导出整个数据库,定义游标,取出所有的用户表
declare @m_tbname varchar(250)
if right(@filename,1)’’ set @filename=@filename+’’
set @m_tbname=’declare #tb cursor for select name from ’+@tbname+’..sysobjects where xtype=’’U’’’
exec(@m_tbname)
open #tb
fetch next from #tb into @m_tbname
while @@fetch_status=0
begin
set @sql=’bcp ’+@tbname+’..’+@m_tbname
+case when @isout=1 then ’ out ’ else ’ in ’ end
+’ “’+@filename+@m_tbname+’.txt ” /w’
+’ /S ’+@servername
+case when isnull(@username,’’)=’’ then ’’ else ’ /U ’+@username end
+’ /P ’+isnull(@password,’’)
exec master..xp_cmdshell @sql
fetch next from #tb into @m_tbname
end
close #tb
deallocate #tb
end
go
/**********************Excel导到Txt****************************************/
想用
select * into opendatasource(...) from opendatasource(...)
实现将一个Excel文件内容导入到一个文本文件
假设Excel中有两列,第一列为姓名,第二列为很行帐号(16位)
且银行帐号导出到文本文件后分两部分,前8位和后8位分开,
(MS SQL Server)SQL语句导入导出大全数据库教程
,
如果要用你上面的语句插入的话,文本文件必须存在,而且有一行:姓名,银行账号1,银行账号2
然后就可以用下面的语句进行插入
注意文件名和目录根据你的实际情况进行修改.
insert into
opendatasource(’MICROSOFT.JET.OLEDB.4.0’
,’Text;HDR=Yes;DATABASE=C:’
)...[aa#txt]
--,aa#txt)
--*/
select 姓名,银行账号1=left(银行账号,8),银行账号2=right(银行账号,8)
from
opendatasource(’MICROSOFT.JET.OLEDB.4.0’
,’Excel 5.0;HDR=YES;IMEX=2;DATABASE=c:a.xls’
--,Sheet1$)
)...[Sheet1$]
如果你想直接插入并生成文本文件,就要用bcp
declare @sql varchar(8000),@tbname varchar(50)
--首先将excel表内容导入到一个全局临时表
select @tbname=’[##temp’+cast(newid() as varchar(40))+’]’
,@sql=’select 姓名,银行账号1=left(银行账号,8),银行账号2=right(银行账号,8)
into ’+@tbname+’ from
opendatasource(’’MICROSOFT.JET.OLEDB.4.0’’
,’’Excel 5.0;HDR=YES;IMEX=2;DATABASE=c:a.xls’’
)...[Sheet1$]’
exec(@sql)
--然后用bcp从全局临时表导出到文本文件
set @sql=’bcp “’+@tbname+’” out “c:aa.txt” /S“(local)” /P“” /c’
exec master..xp_cmdshell @sql
--删除临时表
exec(’drop table ’+@tbname)
用bcp将文件导入导出到数据库的存储过程:
/*--bcp-二进制文件的导入导出
支持image,text,ntext字段的导入/导出
image适合于二进制文件;text,ntext适合于文本数据文件
注意:导入时,将覆盖满足条件的所有行
导出时,将把所有满足条件的行也出到指定文件中
此存储过程仅用bcp实现
邹建 2003.08-----------------*/
/*--调用示例
--数据导出
exec p_binaryIO ’zj’,’’,’’,’acc_演示数据..tb’,’img’,’c:zj1.dat’
--数据导出
exec p_binaryIO ’zj’,’’,’’,’acc_演示数据..tb’,’img’,’c:zj1.dat’,’’,0
--*/
if exists (select * from dbo.sysobjects where id = object_id(N’[dbo].[p_binaryIO]’) and OBJECTPROPERTY(id, N’IsProcedure’) = 1)
drop procedure [dbo].[p_binaryIO]
GO
Create proc p_binaryIO
@servename varchar (30),--服务器名称
@username varchar (30), --用户名
@password varchar (30), --密码
@tbname varchar (500), --数据库..表名
@fdname varchar (30), --字段名
@fname varchar (1000), --目录+文件名,处理过程中要使用/覆盖:@filename+.bak
@tj varchar (1000)=’’, --处理条件.对于数据导入,如果条件中包含@fdname,请指定表名前缀
@isout bit=1 --1导出((默认),0导入
AS
declare @fname_in varchar(1000) --bcp处理应答文件名
,@fsize varchar(20) --要处理的文件的大小
,@m_tbname varchar(50) --临时表名
,@sql varchar(8000)
--则取得导入文件的大小
if @isout=1
set @fsize=’0’
else
begin
create table #tb(可选名 varchar(20),大小 int
,创建日期 varchar(10),创建时间 varchar(20)
,上次写操作日期 varchar(10),上次写操作时间 varchar(20)
,上次访问日期 varchar(10),上次访问时间 varchar(20),特性 int)
insert into #tb
exec master..xp_getfiledetails @fname
select @fsize=大小 from #tb
drop table #tb
if @fsize is null
begin
print ’文件未找到’
return
end
end
--生成数据处理应答文件
set @m_tbname=’[##temp’+cast(newid() as varchar(40))+’]’
set @sql=’select * into ’+@m_tbname+’ from(
select null as 类型
union all select 0 as 前缀
union all select ’+@fsize+’ as 长度
union all select null as 结束
union all select null as 格式
) a’
exec(@sql)
select @fname_in=@fname+’_temp’
,@sql=’bcp “’+@m_tbname+’” out “’+@fname_in
+’” /S“’+@servename
+case when isnull(@username,’’)=’’ then ’’
else ’” /U“’+@username end
+’” /P“’+isnull(@password,’’)+’” /c’
exec master..xp_cmdshell @sql
--删除临时表
set @sql=’drop table ’+@m_tbname
exec(@sql)
if @isout=1
begin
set @sql=’bcp “select top 1 ’+@fdname+’ from ’
+@tbname+case isnull(@tj,’’) when ’’ then ’’
else ’ where ’+@tj end
+’” queryout “’+@fname
+’” /S“’+@servename
+case when isnull(@username,’’)=’’ then ’’
else ’” /U“’+@username end
+’” /P“’+isnull(@password,’’)
+’” /i“’+@fname_in+’”’
exec master..xp_cmdshell @sql
end
else
begin
--为数据导入准备临时表
set @sql=’select top 0 ’+@fdname+’ into ’
+@m_tbname+’ from ’ +@tbname
exec(@sql)
--将数据导入到临时表
set @sql=’bcp “’+@m_tbname+’” in “’+@fname
+’” /S“’+@servename
+case when isnull(@username,’’)=’’ then ’’
else ’” /U“’+@username end
+’” /P“’+isnull(@password,’’)
+’” /i“’+@fname_in+’”’
exec master..xp_cmdshell @sql
--将数据导入到正式表中
set @sql=’update ’+@tbname
+’ set ’+@fdname+’=b.’+@fdname
+’ from ’+@tbname+’ a,’
+@m_tbname+’ b’
+case isnull(@tj,’’) when ’’ then ’’
else ’ where ’+@tj end
exec(@sql)
--删除数据处理临时表
set @sql=’drop table ’+@m_tbname
end
--删除数据处理应答文件
set @sql=’del ’+@fname_in
exec master..xp_cmdshell @sql
go
/** 导入文本文件
EXEC master..xp_cmdshell ’bcp “dbname..tablename” in c:DT.txt -c -Sservername -Usa -Ppassword’
改为如下,不需引号
EXEC master..xp_cmdshell ’bcp dbname..tablename in c:DT.txt -c -Sservername -Usa -Ppassword’
/** 导出文本文件
EXEC master..xp_cmdshell ’bcp “dbname..tablename” out c:DT.txt -c -Sservername -Usa -Ppassword’
【实验三sql查询语句】推荐阅读:
sql简单查询语句09-15
数据查询实验报告01-24
数据库查询语句大全10-23
sql大作业实验报告07-03
sql数据库实验报告07-27
社保查询个人账户怎么查询01-07
个人信息查询及留存授权书(个人征信查询)01-16
出生证明查询09-08
审计报告查询11-15
实验十三综合实验01-04