MSSQL之十一 数据库高级编程总结(下)

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: MSSQL之十一 数据库高级编程总结(下)

四.SQLServer异构数据库之间数据的导入导出

 

本文讨论了如何通过Transact-SQL以及系统函数OPENDATASOURCE和OPENROWSET在同构和异构数据库之间进行数据的导入导出,并给出了详细的例子以供参考。


1. 在SQL Server数据库之间进行数据导入导出

 (1).使用SELECT INTO导出数据  


在SQL Server中使用最广泛的就是通过SELECTINTO语句导出数据,SELECT INTO语句同时具备两个功能:根据SELECT后跟的字段以及INTO后面跟的表名建立空表(如果SELECT后是*, 空表的结构和FROM所指的表的结构相同);将SELECT查出的数据插入到这个空表中。在使用SELECT INTO语句时,INTO后跟的表必须在数据库不存在,否则出错,下面是一个使用SELECT INTO的例子。


假设有一个表table1,字段为f1(int)、f2(varchar(50))。


SELECT * INTO table2 FROM table1


这条SQL语的在建立table2表后,将table1的数据全部插入到table1中的,还可以将*改为f1或f2以便向适当的字段中插入数据。


SELECT INTO不仅可以在同一个数据中建立表,也可以在不同的SQL Server数据库中建立表。


USE db1


SELECT * INTO db2.dbo.table2 FROM table1


以上语句在数据库db2中建立了一个所有者是dbo的表table2,在向db2建表时当前登录的用户必须有在db2建表的权限才能建立table2。使用SELECT INTO要注意的一点是SELECT INTO不可以和COMPUTE一起使用,因为COMPUTE返回的是一组记录集,这将会引起二意性(即不知道根据哪个表建立空表)。


(2).使用INSERTINTO和 UPDATE插入和更新数据


SELECT INTO只能将数据复制到一个空表中,而INSERT INTO可以将一个表或视图中的数据插入到另外一个表中。


INSERT INTO table1 SELECT * FROM table2


或 INSERT INTO db2.dbo.table1 SELECT * FROMtable2


但以上的INSERT INTO语句可能会产生一个主键冲突错误(如果table1中的某个字段是主键,恰巧table2中的这个字段有的值和table1的这个字段的值相同)。因此,上面的语句可以修改为


INSERT INTO table1   -- 假设字段f1为主键


SELECT * FROM table2 WHERE NOT EXISTS(SELECTtable1.f1 FROM table1 WHERE table1.f1=table2.f1 )


以上语句的功能是将table2中f1在table1中不存在的记录插入到table1中。


要想更新table1可以使用UPDATE语句


UPDATE table1 SET table1.f1=table2.f1,table1.f2=table2.f2 FROM table2 WHERE table1.f1=table2.f1


将以上两条INSERT INTO和UPDATE语句组合起来在一起运行,就可以实现记录在table1中不存在时插入,存在时更新的功能,但要注意要将UPDATE放在 INSERT INTO前面,否则UPDATE更新的记录数将是table1和table2记录数的总和。


 2. 使用OPENDATASOURCE和OPENROWSET在不同类型的数据库之间导入导出数据

在异构的数据库之间进行数据传输,可以使用SQL Server提供的两个系统函数OPENDATASOURCE和OPENROWSET。


OPENDATASOURCE可以打开任何支持OLE DB的数据库,并且可以将OPENDATASOURCE做为SELECT、UPDATE、INSERT和DELETE后所跟的表名。如


SELECT * FROM OPENDATASOURCE('SQLOLEDB', 'DataSource=192.168.18.252;User ID=sa;Password=test').pubs.dbo.authors


这条语句的功能是查询192.168.18.252这台机器中SQL Server数据库pubs中的authors表。从这条语句可以看出,OPENDATASOURCE有两个参数,第一个参数是 provider_name,表示用于访问数据源的 OLE DB 提供程序的 PROGID 的名称。provider_name 的数据类型为 char,没有默认值。第二个参数是连接字符串,根据OLE DB Provider不同而不同(如果不清楚自己所使用的OLE DBProvider的连接字符串,可以使用delphi、visualstudio等开发工具中的ADO控件自动生成相应的连接字符串)。


OPENROWSET函数和OPENDATASOURCE函数类似,只是它可以在打开数据库的同时对数据库中的表进行查询,如以下语句


OPENROWSET('MSDASQL.1', 'Driver=Microsoft VisualFoxPro Driver; SourceDB=c:\db; SourceType=DBF', SELECT * FROM [b.dbf])


最后一个参数查询foxpro表b.dbf,读者可以通过where条件对b.dbf进行过滤。如果将INSERT INTO、SELECT INTO和OPENDATASOURCE或OPENROWSET一起使用,就可以使SQL Server数据库和其它类型的数据库之间进行数据导入导出。下面介绍如何使用这两个函数在SQL Server数据库和其它类型的数据库之间进行数据导入导出。


 (1).SQLServer数据库和SQL Server数据库之间的数据导入导出。


导入数据


SELECT   * INTOauthors1 FROMOPENDATASOURCE( 'SQLOLEDB', 'Data Source=192.168.18.252;UserID=sa;Password=abc').pubs.dbo.authors


导出数据


INSERT INTO OPENDATASOURCE('SQLOLEDB','DataSource=192.168.18.252;User ID=sa;Password=abc').test.dbo.authors select * frompubs.dbo.authors


在这条语句中OPENDATASOURCE(...)可以理解为SQL Server的一个服务,.pubs.dbo.authors是这个服务管理的一个数据库的一个表authors。使用INSERT INTO时OPENDATASOURCE(...)后跟的表必须存在。


也可以将以上的OPENDATASOURCE换成OPENROWSET


INSERT INTO OPENROWSET('SQLOLEDB','192.168.18.252;sa;abc',select * from test.dbo.kk) SELECT * FROM pubs.dbo.authors


使用OPENROWSET要注意一点,192.168.18.252;sa;abc中间是";",而不是","。OPENDATASOURCE和OPENROWSET都不接受参数变量。


 (2).SQL Server数据库和Access数据库之间的数据导入导出。


导入数据


SELECT * INTO access FROM OPENDATASOURCE( 'Microsoft.Jet.OLEDB.4.0','Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\data.mdb;Persist SecurityInfo=False')...table1


或者使用OPENROWSET


SELECT * FROM  OPENROWSET('Microsoft.Jet.OLEDB.4.0', 'c:\data.mdb;admin;',SELECT * FROMtable1)


导出数据


INSERT INTOOPENDATASOURCE('Microsoft.Jet.OLEDB.4.0','Provider=Microsoft.Jet.OLEDB.4.0;DataSource=c:\data.mdb;Persist Security Info=False')...table1 SELECT * FROM access


打开access数据库的OLE DBProvider叫Microsoft.Jet.OLEDB.4.0,需要注意的是操作非SQL Server数据库在OPENDATASOURCE(...)后面引用数据库中的表时使用"...”,而不是“.”。


 (3).SQL Server数据库和文本文件之间的数据导入导出。


导入数据


SELECT * INTO text1 FROMOPENDATASOURCE('MICROSOFT.JET.OLEDB.4.0','Text;DATABASE=c:\')...[data#txt]


导出数据


INSERT INTOOPENDATASOURCE('MICROSOFT.JET.OLEDB.4.0','Text;DATABASE=c:\')...[data#txt]SELECT * FROM text1


或者使用OPENROWSET


INSERT INTOOPENROWSET('MICROSOFT.JET.OLEDB.4.0','Text;DATABASE=c:\, [data#txt]') SELECT *FROM text1


如果要插入部分字段,可使用


INSERT INTOOPENROWSET('MICROSOFT.JET.OLEDB.4.0','Text;DATABASE=c:\, SELECT aa FROM[data#txt]') SELECT aa FROM text1


这条SQL语句的功能是将c盘根目录的data.txt文件导入到text1表中,在这里文件名中的“.”要使用“#”代替。在向文本导出时,不仅文本文件要存在,而且第一行必须和要导出表的字段一至。


   (4).SQL Server数据库和dbase数据库之间的数据导入导出。


导入数据  


SELECT * INTO dbase FROMOPENROWSET('MICROSOFT.JET.OLEDB.4.0 ', 'dBase III;HDR=NO;IMEX=2;DATABASE=C:\',SELECT* FROM [b.dbf])


导出数据


INSERT INTO OPENROWSET('MICROSOFT.JET.OLEDB.4.0', dBase III;HDR=NO;IMEX=2;DATABASE=C:\,SELECT * FROM [b.dbf]) SELECT * FROMdbase


OPENROWSET(...)中的b.dbf使用[...]括起来,是为了当dbf文件名有空格等字符时不会出错,如果没有这些特殊字符,可以将[...]去掉


 (5).SQL Server数据库和foxpro数据库之间的数据导入导出。


导入数据


SELECT * INTO foxpro FROMOPENROWSET('MSDASQL.1',   'Driver=Microsoft Visual FoxProDriver;SourceDB=c:\; SourceType=DBF, 'SELECT * FROM [a.dbf])


导出数据


INSERT INTO OPENROWSET('MSDASQL.1' ,'Driver=Microsoft Visual FoxPro Driver;  SourceDB=c:\db;SourceType=DBF,'SELECT * FROM a.dbf) SELECT * FROM foxpro


在此处a.dbf不能使用[...]括起来,否则出错(这是由driver决定的)。


 (6).SQL Server数据库和excel文件之间的数据导入导出


导入数据


SELECT * INTO excel FROMOPENDATASOURCE(MICROSOFT.JET.OLEDB.4.0,Excel 5.0;DATABASE=c:\book1.xls)...[Sheet1$]


导出数据


INSERT INTOOPENDATASOURCE(MICROSOFT.JET.OLEDB.4.0,Excel 5.0;DATABASE=c:\book1.xls)...[Sheet1$] SELECT * FROM excel


在book1.xls的Sheet1中必须有和excel表相对应的字段,否则会出错。


以上讨论了几种常用的数据库和SQL Server数据库之间如何使用Transact-SQL进行数据导入导出。在SQL Server中还提供了将其它类型的数据库注册到SQL Server中的功能,这样就可以和使用SQL Server数据库表一样使用这些被注册数据库中的表了。


EXEC sp_addlinkedserver access,OLE DB Providerfor Jet, Microsoft.Jet.OLEDB.4.0, c:\data.mdb


以上SQL使用存储过程sp_addlinkedserver注册了一个access数据库,我们可以在SQL Server中使用如下语句查询在data.mdb中的table1。


 SELECT * FROM access...table1


这样就可很方便地查询access数据库中的表了,如果要导入table1,可以使用SELECT * INTO table2 FROMaccess...table1。如果想删除注册的数据库连接,使用如下语句。


 EXEC sp_dropserver access


使用Transact-SQL不仅可以向SQLServer数据库导入导出数据,而且还可以使任意两种类型数据库之间互相导入导出数据。以access和excel为例进行说明。    


INSERT INTOOPENDATASOURCE(MICROSOFT.JET.OLEDB.4.0,Excel 5.0;DATABASE=c:\book1.xls)...[Sheet1$] SELECT * FROM OPENROWSET(Microsoft.Jet.OLEDB.4.0,c:\data.mdb;admin;,SELECT * FROM table1)


以上SQL语句将access数据库的table1表的数据插入到excel文件book1.xls中的Sheet1表单中。


使用Transact-SQL进行数据的导入导出,可以很方便地将这些Transact-SQL语句放到客户端程序中(如delphi、c#等),从而可以很容易地编写自已的数据库导入导出工具。



五.无限级分类的数据库设计方案



第一种方案:


表为两张,一张分类表,一张信息表。

表1:

`ID` int(10),

`cID` tinyint(3) ,

`title` varchar(255),

表2:

`cID` tinyint(3) ,

`parentID` tinyint(3),

`order` tinyint(3) ,

`name` varchar(255),


这样可以根据cID = parentID来判断上一级内容,运用递归至最顶层 。


第二种方案:


设置parentID为varchar类型,将父类id都集中在这个字段里,用符号隔开,比如:1,3,6

这样可以比较容易得到各上级分类的ID,而且在查询分类下的信息的时候,可以使用如:Select * From information Where cID Like "1,3%"。不过在添加分类和转移分类的时候操作将非常麻烦。


以上两种方案地址:http://search.phpres.com/phpres-top2007,98552.html


第三种方案:


每级分类递增两位数字,这样,每级分类的数目限定在100个之间,分类方法主要为编码法;

示例:

一级分类:01,02,03

二级分类:0101,0102,0103,0201,0202........

三级分类:010101,010102,010103,010104..........


数据库查询时使用 like '01%'就可得到一级分类01下的所有子分类,非常方便!

如果要列出所有分类的树型结构,只需用一条语句select * from pro_class order bycode,再稍微处理一下就可。(其中,pro_class为产品分类表,code为类别编码)。



设计的数据库结构如下:


id:                   类别id,主键

classname:         类名

classcode:          类别编码

parent:             父id

left_child:          最左孩子id(或第一个孩子)

right_sibling:      右兄弟id

layer:                层级(第一级类别为1,第2级类别2,以此类推)


相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
4月前
|
Java 数据库连接 网络安全
JDBC数据库编程(java实训报告)
这篇文章是关于JDBC数据库编程的实训报告,涵盖了实验要求、实验环境、实验内容和总结。文中详细介绍了如何使用Java JDBC技术连接数据库,并进行增删改查等基本操作。实验内容包括建立数据库连接、查询、添加、删除和修改数据,每个部分都提供了相应的Java代码示例和操作测试结果截图。作者在总结中分享了在实验过程中遇到的问题和解决方案,以及对Java与数据库连接操作的掌握情况。
JDBC数据库编程(java实训报告)
|
3月前
|
存储 数据库 Python
python的对象数据库ZODB的使用(python3经典编程案例)
该文章介绍了如何使用Python的对象数据库ZODB来进行数据存储,包括ZODB的基本操作如创建数据库、存储和检索对象等,并提供了示例代码。
46 0
|
3月前
|
JSON NoSQL 数据库
和SQLite数据库对应的NoSQL数据库:TinyDB的详细使用(python3经典编程案例)
该文章详细介绍了TinyDB这一轻量级NoSQL数据库的使用方法,包括如何在Python3环境中安装、创建数据库、插入数据、查询、更新以及删除记录等操作,并提供了多个编程案例。
127 0
|
4月前
|
Linux 数据库 数据安全/隐私保护
|
3月前
|
SQL 存储 数据库
MSSQL遍历数据库根据列值查询数据
【9月更文挑战第12天】在 SQL Server 中,可以通过游标或临时表遍历数据库并根据列值查询数据。示例展示了如何创建临时表存储数据库名,并通过循环遍历这些名称来执行特定查询。需替换 `YourTableName`、`YourColumnName` 和 `YourValue` 为实际值。此方法要求有足够权限访问各数据库。若无跨库权限,需分别执行查询。
|
4月前
|
存储 SQL 数据库
|
4月前
|
SQL 数据库 索引
SQL 编程最佳实践简直太牛啦!带你编写高效又可维护的 SQL 代码,轻松应对数据库挑战!
【8月更文挑战第31天】在SQL编程中,高效与可维护的代码至关重要,不仅能提升数据库性能,还降低维护成本。本文通过案例分析探讨SQL最佳实践:避免全表扫描,利用索引加速查询;合理使用JOIN,避免性能问题;避免使用`SELECT *`,减少不必要的数据传输;使用`COMMIT`和`ROLLBACK`确保事务一致性;添加注释提高代码可读性。遵循这些实践,不仅提升性能,还便于后期维护和扩展。应根据具体情况选择合适方法并持续优化SQL代码。
56 0
|
4月前
|
存储 SQL 数据库
【计算机三级数据库技术】第8章 数据库后台编程技术--附思维导图
本文介绍了数据库后台编程的关键技术,包括存储过程、用户定义函数、触发器和游标,并附有思维导图。
36 1
|
4月前
|
SQL 关系型数据库 MySQL
"Python与MySQL的浪漫邂逅:一键掌握增删改查,开启你的数据库编程之旅!"
【8月更文挑战第21天】Python因其简洁的语法和强大的库支持,成为连接数据库的首选工具。本文介绍如何使用Python连接MySQL数据库并执行基本操作。首先需安装`mysql-connector-python`库。通过配置连接信息建立数据库连接后,可利用`cursor.execute()`执行SQL语句进行数据的增删改查,并通过`commit()`提交更改。查询时使用`fetchall()`或`fetchone()`获取结果。记得处理异常及关闭连接以释放资源。掌握这些基础,有助于高效进行数据库编程。
66 0
|
6月前
|
SQL XML Java
后端数据库开发JDBC编程Mybatis之用基于XML文件的方式映射SQL语句实操
后端数据库开发JDBC编程Mybatis之用基于XML文件的方式映射SQL语句实操
74 3

热门文章

最新文章

下一篇
无影云桌面