记录生活和工作的点滴
0

DOS是怎样进行内存管理的

 

342.DOS是怎样进行内存管理的?
内存是计算机中存储程序代码以及数据的地方,是程序赖以运行的舞台。内存在计算机中编址,形成了内存地址空间,既包括了RAM内存,也包括了ROM内存。通常的内存
编址方法是按字节(8bit进行的,1M内存便是指大小为1兆字节的内存空间。以PC机为例,早期的8086/8088系统共有20根地址线,则可寻址2^20=1M字节;80286系统则有
24根地址线,相应可寻址2^24=16M字节,到了386、486,地址总线宽度扩大到了32根,可寻址的内存空间也扩大为4G字节。
内存地址空间又称为物理地址空间,它是实际主存储器的大小;相对有虚拟地址空间的概念,也称逻辑地址空间,它指的是应用程序的编级地址空间。二者有时等同,有时相互区别,这取决于系统的内存管理策略。
无论是早期的DOS版本,还是最近的6.22;DOS下直接使用的都是物理地址空间。如果要使用逻辑地址空间,你必须自己编程。这一点,我们后面还要讲到。
DOS是单用户单作业操作系统,因此采用的是固定分区内存管理技术,把内存低端部分(1M以下)固定地分成系统区和用户区(TPA),见图4-3。
当前版本的MS—DOS可以管理1MB的物理地址空间。在IBMPC及其兼容机上,由MS-DOS和其他程序所占的内存在地址0000H处开始,并可达地址09FFFFH,此640KB的RAM区域有时称为“常规内存区”。此地址以上的内存区是为ROM硬件驱动程序、视频刷新缓冲区等所保留的。非IBM兼容机有可能使用其他内存区段。在MS—DOS控制下的RAM区可分成两个主要部分:
操作系统区域
临时程序区域(TPA)


操作系统区域在地址0000H处开始,即它占用RAM的最低部分。该处有中断向量表、操作系统模块及其所拥有的表(table)和缓冲区,以及 config.sys)文件中指定的附加可安装设备驱动程序及command.com命令解释程序的驻留部分。操作系统区所占的内存量随MS-DOS版本、磁盘缓冲区数、可安装设备驱动程序个数与大小而改变。
临时程序区为RAM中所存操作系统区上面的剩余部分,是动态可分配的内存。DOS将在应用程序运行时总是试图把这部分内存分配给它,必要时系统区1(参见图4—3)将腾出以扩大TPA区。如果此区过小,则会出现。out of memory内存不够的错误,你的应用程序将无法运行。 
当出现此错误时,在低版本DOS中将是一筹莫展,在8086/8088中亦是如此,最多能做到的是不装载任何TSR程序。这意味着你甚至需要牺牲鼠标器支持;而高版本DOS则可以利用将要讲到的两点功能(1)把DOS自身一部分装载到HMA中,(2)把TSR程序和驱动程序装载到UMB,从而达到扩大 TPA,供应用程序运行的目的。
对于1M以上的内存,DOS将无能为力,除了下面将要讲到HMA以外。


================================================================
343.为什么在386、486的计算机上虽然有4M或更多的内存配置,却总是会出现“内存不够”的错误?

这正是DOS的局限性所带来的。从前面的问题中我们可以看出,在DOS中,真正供应用程序运行区域是TPA。DOS为了保持与8086/8088系统兼容性,把TPA限制在1M以下.所以有时计算机虽有4M或更多内存,你也无法直接使用。当然,1M以上的内存也还是可以利用的。

(1)在保护模式下,你可以直接寻址1M以上空问。DOS是无法做到这一点,而Windows或OS/2等其他操作系统可以做到。
(2)利用DOS提供的工具,间接访问1M以上空间,如EMS或XMS技术。关于EMS和XMS请参见《如何使用扩充内存(Expanded)》和《如何使用扩展内存Extended)》。


===============================
346.什么是常规内存、扩充内存、扩展内存?

常规内存(Conventional Memory)是指从00000H到9FFFPH这640k的内存空间,它是DOS的传统势力范围.DOS对这一段的划分和管理请参阅《DOS是怎样进行内存管理的》。

扩充内存(Expanded Memory)是一种不参与存储器统一统址的内存。其使用规范称作EMS(Expanded Memory Sepecfication),因为是由Lotus,Intel和Microsoft三家公司联合开发的,故也称作LIM EMS。早期XT机型上扩充内存以内存卡的物理形式出现,后来的高档微机上则可以由扩展内存(Extended Memory)来仿真扩充内存,这是CPU开始支持内存映射的结果。

扩展内存是原1MB内存空间的纵向延伸.这种内存只存在于80286以上的机型之中。这种内存,只是在“保护(protected)”方式时是可寻址的; DOS运行于real方式(实模式),仿真8086寻址空间,因此标准的DOS应用程序是不能直接访问它的。对286来说,CPU共有24根地址线,其扩展内存可达15MB,而在386,486或更高档机器上。扩展内存可拥有4GB-1MB的大小,这是因为它们的地址总线宽度为32位。

===============================
347 如何使用扩充内存(Expanded Memory)?

因为扩充内存没有统一编址,所以CPU不能象访问普通的主存那样通过地址线来直接访问它。这中间就需要扩充内存管理程序EMM,也既是软件技术的支持。
对扩充内存的访问有些像日常去图书馆借书。你是没有权力进入书库象查检自己的书柜那样进行“访问”的,只有去到柜台那儿,交给管理员小姐您的索书单,她便进库去找寻您要的书,找到之后回来再为您办理手续——如果把书库看作您自家书柜这一主存的扩充内存的话,管理员小姐便是EMM,您便是CPU。柜台呢,则称作页框.
页框的大小是64K,为什么是64K呢?您一定记得8086的段式访问机制,一个段的大小便是64k。这样,只要知道了页框起始处的段地址,就可以通过一个偏移量指针遍历整个页框,如果超过64K,那就需要调整段地址了.
或许EMS的设计者考虑到内存的使用效率而把扩充内存以16k为单位进行组织划分,而不是一个页框的大小。现在EMS内中的每16k就称作一页,那么 CPU同时也就只能“看见”扩充内存其中四页,虽然程序可以申请到不止四页的扩充内存。这自然类似于图书馆的制度,您可以“借”图书馆的许多书,甚至全部的书,但一次您只能“惜到”十本书,看
完归还之后再来借.
编程中对扩充内存进行访问的步骤大致如下:
(1)EMM安装了没有?
无论是EMM386.EXE还是QEMM386.SYS等EMM程序,具有统一的设备名“EMMxxxx”,我们可以通过判断此设备是否安装来判断EMM存在与否?
(2)页框起始地址在何处?
这是判断EMM已安装后的第二个步骤。页框是我们“看到”EMS内存的窗口,当然首先要找到它。
(3)申请EMS内存

如果您估计您的程序数据量不会超过1MB,那就申请64页的扩充内存好了(当然要实际存在如此多的扩充内存才可以,EMM不可能无中生有),申请到的EMS内存由一个称作句柄的整数来标志管理.
当然您可以随时根据需要多次申请EMS内存,只不过处理多个句柄总是要多些麻烦。
(4)映射EMS内存
申请到了一些EMS内存页面,意味着你可以“看”它们,但迄今为止它们并不“可见”,还需要进行映射。映射的意思,也就告诉EMM,让它把哪一个句柄的哪四页(少一些页自然可以),放到页框这个窗口中来。
做完映射工作之后,您就可以往页框中存放,读取数据了.当这几页用完之后.再映射其它几页到页框中,而原来的四页则不再‘可见’。如此这般,您就可以把您大量的数据存放到EMS内存中。
(5)释放EMS内存
当工作完成之后,还需要把申请到的EMS内存加以释放,因为EMM无法判断程序的结束而主动地来完成这项工作。
这一系列步骤使得EMS内存的使用看起来有些麻烦。的确,EMS内存的使用在一定程度上降低了系统性能.但这是值得的,要知道世界上没有免费的午餐.
。。。。。。

==================================
   348.如何使用扩展内存(Extended Memory)?

早期在DOS下访问扩展内存,必须通过BIOS中断INT l5H,但是因为该接口功能不够严谨,各软件之间容易因为使用扩展内存而发生冲突.有鉴于此,1988年底Microsoft,
Intel,Lotus和AST四家公司共同开发出了关于存取扩展内存的标准,这就是扩展内存规范XMS(Extended Memory Specification).
为了兼容性,大多数XMS驱动程序都可以为INT l5H保留一席之地.
DOS及DOS应用程序无法直接访问扩展内存,必须通过XMS功能接口达到目的.
XMS编程大致可分以下几个步骤:
(1)判断XMS是否已安装
这一点可以通过调用INT 2FH的4300H 号子功能来实现,通常INT 2FH以其“假脱机打印”功能而闻名。
功能调用之后,若寄存器AL=80H 表示XMS驱动程序已安装,反之则否.
(2)申请XMS内存块 ’
XMS编程接口有一点很特殊,不同于一般的中断调用,就是各子功能的执行是要对XMS驱动程序入口点进行远调用,而不是中断调用.
XMS驱动程序的入口地址可以通过INT 2FH的子功能4310H号来得到.调用完毕后,ES:BX即为入口点.
。。。。。。

(3)数据的存取
申请到了扩展内存,但我们并不能直接使用它,仍需要先把数据存放在一个常规内存缓冲区内,待恰当时机再把数据从缓冲区移到扩展内存之中.这一点对应XMS的0BH 号子功能:移动扩展内存块。

(4)释放扩展内存
该子功能号为0AH,入口参数为要释放的扩展内存块的句柄.
对于上面的讨论,请进一步阅读有关资料,以得到更详尽的信息.
下面给出一个完整的例子,供你参考。
。。。。。。


==================================
349.什么是UMB? 如何使用UMB?

640K~1MB这一段地址空间是微机的设计者保留下来给系统以及外部扩展设备来使用的,因此在这一段之中没有系统板上的RAM.如果您的机器配置了 1MB的内存,并且机器没有打开明SHADOW功能的话,将会有384k的扩展内存,此时RAM最高地址为1408K。
这一段地址空间某些部分的分配是比较固定的:
。。。。。。
其他部分的地址空间则没有固定地被占用,由其他硬件扩展设备,如汉卡、网卡等等来选择.一般情况下,这些空闲地址空间可用来再生成上位内存块UMB,供DOS利用.
让我们来看一个VGA配置的PC兼容机有多大的空闲空间。首先B000—B7FF这一段32k的空闲,再就是从C800开始到EFFF结束的这一段,大小为160k——所以我们总共可以有192KB的空间提供给DOS。如果再算上HMA 64K的话,就意味着DOS拥有
了896k=(640+192+64)K 的空间!
事情总要打点折扣,首先如果你安装了网卡,便只有牺牲16K的大小(通常情况);如果您的应用程序需要扩充内存,或者通过扩充内存卡获得,或者通过 EMM386.exe等类似的EMM程序利用扩展内存来仿真得到,但都必须在640k--1MB这一段的空闲区内生成一个EMS页框,又会占去64K的大小.
另外一个问题是保留内存中的空闲区并不连续,在插入其他插卡后有可能被再次分割.如果一个网卡占用了E000~E3FF这16K,原选160k的连续空闲区将被分割为两块,一块96K,一块48K。这就使得DOS在把驱动程序、内存驻留程序装载到UMB运行时,不可避免地造成空间浪费,不能充分利用.
这儿是用MSD察看保留内存区的一个例子。
。。。。。。
保留内存区又称上位内存区UMA,所以利用其间的空闲地址再生成的RAM块被称作UMB,也就是上位内存块的意思。
为了使DOS能够利用UMB,仅仅在CONFIG.SYS中加载EMM386.exe之类的UMB Provider程序还是不够的,必须再通过命令DOS=UMB在二者之间建立起联系,这样DOS的DEVICEHIGH、LH命令才起作用,DOS的中断功能调用也才能够访问UMB。如果没有在CONFIG中运行DOS=UMB,则利用MSD、MEM等实用程序将无法看到UMB的影子,但此时应用程序可以直接向UMB Provider程序申请使用UMB。

==================================
350,什么是HMA?如何使用HMA?

高位内存区HMA可能是最近人摸不着头脑的东西,它是1MB以上的第一个64K,其实要少16个字节,也就是65520字节的大小.这一段可以为DOS直接访问。
不是说DOS只能直接访问1MB以下的内存区域吗? 
我们已知道,DOS的寻址方式是8086/8088的段式机制,16位段地址左移四位再加上16位的偏移量形成20位的地址。这样问题便来了,1MB的绝对地址可以写成段:偏移量的形成为FFFF:000FH,也就是该段起于1MB空间的最后一小节FFFF0H 处;如图4-4所示,很明显,该段还有一部分的空间在1MB以上,也就是扩展内存之内.为FFFF:000FH只是该段的第一个小节结束的地方;偏移量还有FFF0的“余量”,
   这“余量”确定的空间显然可以由DOS直接访问,只得把编移量累加上去就行了.该段的1MB以上区域便是HMA,很显然其大小为64K-16B.
从绝对地址的角度看,HMA的第一个字节地址FFFF:0010H 已是21位地址宽度:1000000H.这在8086/8088中将产生地址绕回错误,因为8086/8088只有20根地址线,
第21根子虚乌有,所以1000000H 处即为0000OH 处.这样,“HMA”便成了0000:0000H至0OOO:FFEFH这一段!
早期的一些应用程序利用这一点来作为特殊技巧,达到所需的编程效果,也就是说,它们依赖于地址回绕.所以,到了后来的286、386等机器,虽然CPU拥有了24根、32根的地址总线,解决了8086/8088中16位地址进位超出总线宽度的问题,却为了保持兼容性,并没有把HMA区直接向DOS开放,而是通过—个“开关”进行控制.
这个“开关”便是我们常常见到的A20 line。A20便是第21根地址线,众所周知,计算
机中的总线都是从0开始编号的.
DOS下HMA区的管理由HIMEM.SYS来提供。程序可以控制A20 line的开、关,可以申请使用HMA,但有一点,HMA不能分割使用,也就是说一次只能有一个程序在其间运行.如果在CONFIG.SYS文件中加载了 HIMEM.SYS驱动程序并且同时有DOS=high命令时,MS-DOS将使A20线有效,并为HMA直新定位系统代码.
。。。。。。
笔者建议在编程中不要试图去使用HMA,免得遇到很多不必要的麻烦,利用HMA的最理想方法便是通过在CONFIG.SYS中加载HIMEM.SYS并运行DOS=high命令,把MS-DOS系统代码加载至其中,从而腾出更多的常规内存来.在DOS 6.2版本中,
DOS=high命令可腾出约49K的空间出来.
关于HMA的使用和编程,请进一步阅读有关的详细资料.


=============================
351.如何使用HIMEM.SYS?
HIMEM.SYS是一扩展(Extended)内存管理程序,也就是常说的XMM,它为扩展内存的使用提供了统一接口标准XMS,避免了早期扩展内存使用当中存在的冲突问题;同时HIMEM.SYS还提供对HMA的管理.
HIMEM.SYS必须在CONFIG.SYS中首先加载,这一点很容易理解,在EMM386.EXE加载之后,保留内存区持有UMB出现, HIMEM.SYS也提供对UMB进行管理的接口.如果在CONFIG.SYS没有运行DOS=UMB命令,也即没有建立起DOS和UMB之间的联系时,应用程序可以直接向HIMEM.SYS申请使用UMB.

=============================
       352.如何使用EMM386.EXE?
EMM386.EXE利用扩展(Extended)内存来仿真扩充(Expanded)内存,以提供对需要扩充内存的应用程序的支持,同时它还提供UMB功能,使得一些设备驱动程序和内存驻留程序能够加载至UMB中,从而腾出更多的常规内存。
EMM386.EXE在CONFIG.SYS中必须位于HIMEM.SYS之后来加载,因为它依赖于HIMEM.SYS的扩展内存支持。这二者也都必须使用DEVICE来加载,而不是DEVICEHIGH,这是因为DEVICEHIGH依赖于EMM386.EXE提供的UMB功能。同理,
要在AUTOEXEC.BAT中使用LOADHIGH(LH)命令也必须在CONFIG.SYS中已加载EMM386.EXE前提之下,并使用DOS=UMB命令在DOS和UMB之间建立起联系。

0

条码第十三位(校验位)计算

 

校验码的计算方法 代码位置序号 代码位置序号是指包括校验码在内的,由右至左的顺序号(校验码的代码位置序号为1)。
 
计算步骤 校验码的计算步骤如下:
a.从代码位置序号2开始,所有偶数位的数字代码求和。
b.将步骤a的和乘以3。
c.从代码位置序号3开始,所有奇数位的数字代码求和。
d.将步骤b与步骤c的结果相加。
e.用大于或等于步骤d所得结果且为10最小整数倍的数减去步骤d所得结果,其差即为所求校验码的值。
示例:代码690123456789X1校验码的计算见表B.1。
表1 校验码的计算方法 步 骤
举 例 说 明
1.自右向左顺序编号 位置序号 13 12 11 10 9 8 7 6 5 4 3 2 1 代码 6 9 0 1 2 3 4 5 6 7 8 9 X
2.从序号2开始求出偶数位上数字之和① 9+7+5+3+1+9=34 ①
3. ①*3=② 34×3=102 ②
4.从序号3开始求出奇数位上数字之和③ 8+6+4+2+0+6=26 ③
5. ②+③=④ 102+26=128 ④
6.用大于或等于结果④且为10最小整数倍的数减去④,其差即为所求校验码的值 130-128=2 校验码X1=2 
 
 
select *,
right((10-
((0+SUBSTRING(plu_no,1,1)+SUBSTRING(plu_no,3,1)+SUBSTRING(plu_no,5,1)+SUBSTRING(plu_no,7,1)+SUBSTRING(plu_no,9,1)+SUBSTRING(plu_no,11,1))+
(0+SUBSTRING(plu_no,2,1)+SUBSTRING(plu_no,4,1)+SUBSTRING(plu_no,6,1)+SUBSTRING(plu_no,8,1)+SUBSTRING(plu_no,10,1)+SUBSTRING(plu_no,12,1))*3)%10),1)
 from ba_multi_plu
0

批处理(bat)实现SQLServer数据库备份与还原

 

--1.数据库备份脚本sqlserverbackup.sql

 

-- SQLServer2000数据库系统清理用户数据库日志和备份用户数据库数据脚本

 

declare@dumpfile varchar(50)

declare@msg varchar(70)

   select @dumpfile = 'd:\backup\north' + datename(dw,getdate())+'.bak'

   select @msg=convert(char(26),getdate(),9)+'-----正在清理日志......'

   print @msg

backuptran northwind with truncate_only

if(@@ERROR <> 0 )

begin

   select @msg=convert(char(26),getdate(),9)+'-----清理日志失败或出现异常......'

   print @msg

end

else

begin

   select @msg=convert(char(26),getdate(),9)+'-----清理日志完毕......'

   print @msg

end

   select @msg=convert(char(26),getdate(),9)+'-----开始备份northwind数据库.....'

   print @msg

backupdatabase northwind to disk=@dumpfile

if(@@ERROR <> 0 )

begin

   select @msg=convert(char(26),getdate(),9)+'-----备份数据失败或出现异常'

   print @msg

end

else

begin

   select @msg=convert(char(26),getdate(),9)+'-----数据库备份完毕'

   print @msg

end

 

 

@net start "mssqlserver"

@isql -Usa -Psa -i d:\backup\sqlserverbackup.sql -o d:\backup\sqlserverbackup.out

@echo ……正在备份中……

@pause

 

--2.数据库还原脚本sqlserverrestore.sql

 

 

declare @dumpfile varchar(50)
declare @msg varchar(70)
select @dumpfile = 'e:\myshopbak01\myshoppos.bak'
select @msg=convert(char(26),getdate(),9)
print @msg
restore database myshoppos from disk=@dumpfile
if (@@ERROR <> 0 )
begin
select @msg=convert(char(26),getdate(),9)+'-----还原数据失败或出现异常'
print @msg
end
else
begin
select @msg=convert(char(26),getdate(),9)+'-----数据库还原完毕'
print @msg
end

 

--将下面的脚本保存为: 备份数据库.bat

 

@net start "mssqlserver"

@isql -Usa -Padmin -i d:\backup\sqlserverbackup.sql -o d:\backup\sqlserverbackup.out

@echo ……正在备份中……

@pause

 

--将下面的脚本保存为:还原数据库.bat

 

@echo ******开始还原数据库*****

@net start "mssqlserver"

@isql -Usa -Psa -i d:\backup\sqlserverrestore.sql -o d:\backup\sqlserverrestore.out

@pause

0

bat批处理 SQL2000数据库附加、分离、查询、备份、还原、删除小程序

 

::▇AAA代表在SQL中看到的[要分离、附加的数据库名]
::▇BBB代表[要附加的数据库的位置]            CCC代表[要附加的数据库文件名]            DDD代表[要附加的数据库日志文件名]
::▇EEE代表[指定的数据库实例用户名]          FFF代表[指定的数据库实例用户的密码] (这里指定的实例是"127.0.0.1"或"Local"或"."即指本机SQL自带的实例)
::▇GGG代表[要备份的数据库名]                HHH代表[数据库备份的路径]                III代表[备份后的名字]
::▇JJJ代表[用于还原的数据库备份文件所在的路径+文件名]   KKK代表[还原后的数据库文件所存放的路径]   LLL代表[还原数据库后在SQL中所显示的名称]
::▇MMM代表[要删除的数据库名]
::#**********************************************************************#
::★1、【分离】请编辑AAA
set AAA=ForestFireControl_StandingBook
::----------------------------------------
::★2、【附加】请编辑AAA、BBB、CCC、DDD
set BBB=C:\
set CCC=ForestFireControl_StandingBook.mdf
set DDD=ForestFireControl_StandingBook_log.ldf
::----------------------------------------
::★设定数据库的登入【账号和密码】请编辑EEE、FFF
set EEE=sa
set FFF=sa
::----------------------------------------
::★4、【备份】请编辑GGG、HHH、III
set GGG=ForestFireControl_StandingBook
set HHH=C:\
set III=备份的数据库2.bak
::----------------------------------------
::★5、【还原】请编辑JJJ、KKK、LLL
set JJJ=C:\备份的数据库2.bak
set KKK=C:\
set LLL=ForestFireControl_StandingBook
::----------------------------------------
::★6、【删除】请编辑MMM
set MMM=ForestFireControl_StandingBook
::#**********************************************************************#
REM 选择菜单

Echo ★★★注意:本文件最好不要放在路径名中含有空格的位置上运行(如桌面等位置)    
Echo #**********************************************************************#
Echo              选项如下(可用记事本打开对相应参数重新编辑)
Echo #**********************************************************************#
Echo.
Echo   [1]分离%AAA%数据库
Echo.       
Echo   [2]附加%BBB%下的%CCC%数据库文件   
Echo.
Echo   [3]查看数据库中已存在的非系统表
Echo.
Echo   [4]备份数据库%GGG%到%HHH%%III%
Echo.
Echo   [5]还原"%JJJ%"数据库备份文件为%LLL%.mdf且存放到%KKK%下
Echo.
Echo   [6]彻底删除数据库%MMM%
Echo.
Echo       退出请按其他键
Echo.
Echo #**********************************************************************#
Echo 选择后请按回车进行确认
Echo.
set /P CHS=请选择: [1],[2],[3],[4],[6]?

if /I "%CHS%"=="1" goto 1111
if /I "%CHS%"=="2" goto 2222
if /I "%CHS%"=="3" goto 3333
if /I "%CHS%"=="4" goto 4444
if /I "%CHS%"=="5" goto 5555
if /I "%CHS%"=="6" goto 6666
goto zzzz
::============================================================================
:1111
cls
set XXX=C:\121.sql
Echo 正在清理与此数据库的连接,请等待……
::将下面的这三句语句写到.sql文件里面,再通过下面的第四条语句调用执行这个.sql文件的内容,第五条语句是删除这个.sql文件,第六条语句开始分离
>"%XXX%" Echo use   master                                                                                                   
>>"%XXX%" Echo declare hcforeach cursor global for select 'kill '+rtrim(spid) from sysprocesses where dbid=db_id(N'%AAA%')     
>>"%XXX%" Echo exec   sp_msforeach_worker   '?'                                                                                
Osql -U"%EEE%" -P"%FFF%" -i %XXX%
del %XXX%
OSQL -E -Q "SP_DETACH_DB %AAA%"
::其他例子: osql -U"sa" -P"sa" -S"127.0.0.1" -Q "sp_detach_db '库名'"
Echo.
Echo.
Echo 分离SQL中名为%AAA%的数据库成功
Echo.
set CHS=0
pause
cls
goto dosmenu
::============================================================================
:2222
cls
OSQL -U"%EEE%" -P"%FFF%" -S"127.0.0.1" -Q "sp_attach_db '%AAA%','%BBB%\%CCC%','%BBB%\%DDD%'"
Echo.
Echo.
Echo 附加%BBB%下的数据库文件%CCC%到SQL中成功
Echo.
::★★★ OSQL -U"sa" -P"sa" -S"127.0.0.1" -Q "sp_attach_db '库名','路径\数据文件名','路径\日志文件名'"
set CHS=0
pause
cls
goto dosmenu
::============================================================================
:3333
cls
OSQL -E -Q "SELECT NAME,FILENAME FROM MASTER..SYSDATABASES WHERE name<>'master' and name<>'tempdb' and name<>'model' and name<>'msdb' "
::★★★上面语句中FROM后面的MASTER..SYSDATABASES表示系统自带的MASTER数据库中的SYSDATABASES表
set CHS=0
pause
cls
goto dosmenu
::============================================================================
:4444
cls
del %HHH%%III%
cls
::加上述的del %HHH%%III%语句的作用是为了防止在路径%III%下已经存在同名的数据库备份文件,而导致文件叠加到一块,这也算是SQL2000的一个Bug
Echo 正在备份数据库,在出现成功的提示之前请您耐心等待……
Echo.
Echo.
OSQL -U"%EEE%" -P"%FFF%" -S"127.0.0.1" -d"%GGG%"   -Q "Backup DataBase %GGG% to disk = '%HHH%%III%'"
::★★★OSQL -U"sa" -P"sa" -S"127.0.0.1" -d"CircleImage" -Q "Backup DataBase CircleImage to disk = 'c:\111.db'"
Echo.
Echo.
Echo 恭喜!恭喜!已成功将SQL中的数据库"%GGG%"备份成%HHH%下文件名为"%III%"的文件
Echo.
set CHS=0
pause
cls
goto dosmenu
::============================================================================
:5555
cls
Echo 数据库文件正在还原,在出现还原成功的提示前请您耐心等待……
set XXX=C:\123.sql

>"%XXX%"   Echo DECLARE @bakFile nvarchar(1024);                               
>>"%XXX%" Echo SET @bakFile = N'%JJJ%';                                      
>>"%XXX%" Echo.                               
>>"%XXX%" Echo DECLARE @restorePath nvarchar(1024);                           
>>"%XXX%" Echo SET @restorePath = N'%KKK%';                                  
>>"%XXX%" Echo.
>>"%XXX%" Echo DECLARE @dbname nvarchar(128);                                 
>>"%XXX%" Echo SET @dbname = N'%LLL%';                                       
>>"%XXX%" Echo.
>>"%XXX%" Echo DECLARE @filename nvarchar(128);                              
>>"%XXX%" Echo SET @filename = @dbname;                                      
>>"%XXX%" Echo.
>>"%XXX%" Echo CREATE TABLE #LogicalFileBak(LogicalName nvarchar(128),        
>>"%XXX%" Echo                                 PhysicalName nvarchar(260),       
>>"%XXX%" Echo                                 Type char(1),                     
>>"%XXX%" Echo                                 FileGroupName nvarchar(128),      
>>"%XXX%" Echo                                 [Size] numeric(20,0),             
>>"%XXX%" Echo                                 [MaxSize] numeric(20,0) );       
>>"%XXX%" Echo.
>>"%XXX%" Echo   INSERT #LogicalFileBak EXEC('RESTORE FILELISTONLY FROM DISK = ''' + @bakFile + '''');              
>>"%XXX%" Echo.
>>"%XXX%" Echo   DECLARE cur CURSOR FOR SELECT LogicalName,Type,FileGroupName FROM #LogicalFileBak;                
>>"%XXX%" Echo   DECLARE @LogicalName nvarchar(128),@Type char(1),@FileGroupName nvarchar(128);                     
>>"%XXX%" Echo.
>>"%XXX%" Echo   DECLARE @cmd nvarchar(4000);                                                                       
>>"%XXX%" Echo   SET @cmd = 'RESTORE DATABASE [' + @dbname + '] FROM DISK = ''' + @bakFile + '''';                  
>>"%XXX%" Echo   SET @cmd = @cmd + ' WITH REPLACE'                                                                  
>>"%XXX%" Echo.
>>"%XXX%" Echo   OPEN cur;                                                                                         
>>"%XXX%" Echo   FETCH NEXT FROM cur INTO @LogicalName,@Type,@FileGroupName;                                       
>>"%XXX%" Echo   WHILE @@FETCH_STATUS = 0                                                                           
>>"%XXX%" Echo        BEGIN                                                                                         
>>"%XXX%" Echo             SET @cmd = @cmd + ',MOVE ''' + @LogicalName + ''' TO ''' + @restorePath                   
>>"%XXX%" Echo                             + @filename + CASE WHEN @Type = 'D' AND @FileGroupName = 'PRIMARY'        
>>"%XXX%" Echo                                                    THEN '.mdf'                                        
>>"%XXX%" Echo                                                WHEN @Type = 'D' AND @FileGroupName ^<^> 'PRIMARY'     
>>"%XXX%" Echo                                                    THEN '.ndf'                                       
>>"%XXX%" Echo                                                ELSE '_log.ldf'                                      
>>"%XXX%" Echo                                                END + ''''                                         
>>"%XXX%" Echo             FETCH NEXT FROM cur INTO @LogicalName,@Type,@FileGroupName;                            
>>"%XXX%" Echo        END                                                                                           
>>"%XXX%" Echo   CLOSE cur;                                                                                      
>>"%XXX%" Echo   DEALLOCATE cur;                                                                                   
>>"%XXX%" Echo.
>>"%XXX%" Echo   EXEC(@cmd);                                                                                        
>>"%XXX%" Echo.
>>"%XXX%" Echo   DROP TABLE #LogicalFileBak;                                                                        

Osql -U"%EEE%" -P"%FFF%" -i %XXX%
del %XXX%

Echo.
Echo.
Echo 恭喜!已成功将"%JJJ%"还原成%LLL%,且还原后的文件存放在%KKK%下
Echo.
pause
set CHS=0
cls
goto dosmenu
::============================================================================
:6666
Echo 真的要删除吗?删除后将不可恢复
Echo.
set /P QR=确定删除请按y,放弃删除请按其他键,请选择?
cls
if /I "%QR%"=="y" (
OSQL -U"%EEE%" -P"%FFF%" -S"127.0.0.1" -Q "Drop DataBase %MMM%"
::其他例子:OSQL -U"sa" -P"sa" -S"127.0.0.1" -Q "Drop DataBase 库名"
Echo.
Echo 删除SQL中名为%AAA%的数据库及源文件成功
Echo.
pause
)
set QR=0
set CHS=0
cls
goto dosmenu
::============================================================================
:zzzz
REM 退出
exit


::**************************************************************************************************
::**************************************************************************************************
::**************************************************************************************************
::分离数据库的命令:Sp_detach_db 数据库名
::  连接数据库的命令:Sp_attach_db或者sp_attach_single_file_db
::  sp_attach_db [@dbname =] 'dbname', [@filename1 =] 'filename_n' [,...16]
::  sp_attach_single_file_db [@dbname =] 'dbname', [@physname =] 'physical_name'
::
::使用此方法可以正确附加和分离SQL Sever7.0和SQL Server 2000的数据库文件,要点是备份的时候一定要将mdf和ldf两个文件都备份下来,mdf文件是数据库数据文件,ldf是日志文件。


::OSQL -? 显示帮助(具体如下所示)
::用法: osql [-U 登录 ID] [-P 密码]
::[-S 服务器] [-H 主机名] [-E 可信连接]
::[-d 使用数据库名称] [-l 登录超时值] [-t 查询超时值]
::[-h 标题] [-s 列分隔符] [-w 列宽]
::[-a 数据包大小] [-e 回显输入] [-I 允许带引号的标识符]
::[-L 列出服务器] [-c 命令结束] [-D ODBC DSN 名称]
::[-q "命令行查询"] [-Q "命令行查询" 并退出]
::[-n 删除编号方式] [-m 错误级别]
::[-r 发送到 stderr 的消息] [-V 严重级别]
::[-i 输入文件] [-o 输出文件]
::[-p 打印统计信息] [-b 出错时中止批处理]


::★★★可通过下面的语句查询已有备份库的逻辑文件名,以用于 还原数据库语句操作 中的操作
::OSQL -U"sa" -P"sa" -S"127.0.0.1"   -Q "restore filelistonly from disk ='C:\备份的数据库1'"
::
::OSQL -U"sa" -P"sa" -S"127.0.0.1"   -Q "restore filelistonly from disk ='C:\备份的数据库1'" >>C:\1234.txt

::=============================================================================================
::★★★★★ 还原数据库语句操作
::其中的 数据库的逻辑文件名 和 数据库日志的逻辑文件名 是通过上述的语句来查询的

::格式说明:
::osql -E -d CircleImage -Q "restore database 备份后SQL中看到的数据库名 from disk='用于还原的备份文件的路径+文件名' with move '数据库的逻辑文件名' TO '备份后的路径+实际文件名', MOVE '数据库日志的逻辑文件名' TO '备份后的路径+实际文件名'"

::实例:
::OSQL -U"sa" -P"sa" -S"127.0.0.1" -Q "restore database CircleImage from disk='C:\CircleImage备份' with move 'CircleImage_Data' to 'c:\CircleImage.mdf',move ::'CircleImage_Log' to 'c:\CircleImage_log.ldf'"

::上述这么长的语句中切不可出现回车等换行符,且参数的大小写是不可随意更改的

::=============================================================================================
::★★ 更改数据库备份文件逻辑名的方法:

::alter database 数据库名 modify file (name=逻辑名,newname=新逻辑名)

::事实上,上面的语句是更改了sysfiles和sysfiles1系统表中的name字段。

0

bat批处理 SQL2005数据库附加、分离、查询、备份、还原、删除小程序

 

::▇AAA代表在SQL中看到的[要分离、附加的数据库名]
::▇BBB代表[要附加的数据库的位置]            CCC代表[要附加的数据库文件名]            DDD代表[要附加的数据库日志文件名]
::▇EEE代表[指定的数据库实例用户名]          FFF代表[指定的数据库实例用户的密码] (这里指定的实例是"127.0.0.1"或"Local"或"."即指本机SQL自带的实例)
::▇GGG代表[要备份的数据库名]                HHH代表[数据库备份的路径]                III代表[备份后的名字]
::▇JJJ代表[用于还原的数据库备份文件所在的路径+文件名]   KKK代表[还原后的数据库文件所存放的路径]   LLL代表[还原数据库后在SQL中所显示的名称]
::▇MMM代表[要删除的数据库名]
::#**********************************************************************#
::★1、【分离】请编辑AAA
set AAA=ForestFireControl_StandingBook
::----------------------------------------
::★2、【附加】请编辑AAA、BBB、CCC、DDD
set BBB=C:
set CCC=ForestFireControl_StandingBook.mdf
set DDD=ForestFireControl_StandingBook_log.ldf
::----------------------------------------
::★设定数据库的登入【账号和密码】请编辑EEE、FFF
set EEE=sa
set FFF=saa
::----------------------------------------
::★4、【备份】请编辑GGG、HHH、III
set GGG=ForestFireControl_StandingBook
set HHH=C:
set III=备份的数据库2.bak
::----------------------------------------
::★5、【还原】请编辑JJJ、KKK、LLL
set JJJ=C:\备份的数据库2.bak
set KKK=C:
set LLL=ForestFireControl_StandingBook
::----------------------------------------
::★6、【删除】请编辑MMM
set MMM=ForestFireControl_StandingBook
::#**********************************************************************#
REM 选择菜单

Echo                选项如下(可用记事本打开对相应参数重新编辑)
Echo #*****************************************************************************#
Echo.
Echo   [1]分离%AAA%数据库
Echo.       
Echo   [2]附加 %BBB% 下的%CCC%数据库文件   
Echo.
Echo   [3]查看数据库中已存在的非系统表
Echo.
Echo   [4]备份数据库%GGG%到 %HHH%\%III%
Echo.
Echo   [5]还原" %JJJ% "数据库备份文件为%LLL%.mdf和%LLL%_log.ldf且存放到 %KKK% 下
Echo.
Echo   [6]彻底删除数据库%MMM%
Echo.
Echo       退出请按其他键
Echo.
Echo #*****************************************************************************#
Echo 选择后请按回车进行确认
Echo.
set /P CHS=请选择: [1],[2],[3],[4],[6]?    

if /I "%CHS%"=="1" goto 1111
if /I "%CHS%"=="2" goto 2222
if /I "%CHS%"=="3" goto 3333
if /I "%CHS%"=="4" goto 4444
if /I "%CHS%"=="5" goto 5555
if /I "%CHS%"=="6" goto 6666
goto zzzz
::============================================================================
:1111
cls
set XXX=%Temp%\1.sql
Echo 正在清理与此数据库的连接,请等待……
::将下面的这句语句写到.sql文件里面,再通过下面的第二条语句调用执行这个.sql文件的内容,第三条语句是删除这个.sql文件,第四条语句开始分离
>"%XXX%" Echo alter database %AAA% set offline with rollback after 1;                                                                                
Osql -U"%EEE%" -P"%FFF%" -i %XXX%
del %XXX%
OSQL -E -Q "SP_DETACH_DB %AAA%"
::其他例子: osql -U"sa" -P"sa" -S"127.0.0.1" -Q "sp_detach_db '库名'"
Echo.
Echo.
Echo 分离SQL中名为%AAA%的数据库成功
Echo.
set CHS=0
pause
cls
goto dosmenu
::============================================================================
:2222
cls
OSQL -U"%EEE%" -P"%FFF%" -S"127.0.0.1" -Q "sp_attach_db '%AAA%','%BBB%\%CCC%','%BBB%\%DDD%'"
Echo.
Echo.
Echo 附加%BBB%下的数据库文件%CCC%到SQL中成功
Echo.
::★★★ OSQL -U"sa" -P"sa" -S"127.0.0.1" -Q "sp_attach_db '库名','路径\数据文件名','路径\日志文件名'"
set CHS=0
pause
cls
goto dosmenu
::============================================================================
:3333
cls
OSQL -E -Q "SELECT NAME,FILENAME FROM MASTER..SYSDATABASES WHERE name<>'master' and name<>'tempdb' and name<>'model' and name<>'msdb' "
::★★★上面语句中FROM后面的MASTER..SYSDATABASES表示系统自带的MASTER数据库中的SYSDATABASES表
set CHS=0
pause
cls
goto dosmenu
::============================================================================
:4444
cls
del "%HHH%\%III%"
cls
::加上述的del "%HHH%\%III%"语句的作用是为了防止在路径%III%下已经存在同名的数据库备份文件,而导致文件叠加到一块,这也算是SQL的一个Bug
Echo 正在备份数据库,在出现备份成功的提示之前请您耐心等待……
Echo.
Echo.
OSQL -U"%EEE%" -P"%FFF%" -S"127.0.0.1" -d"%GGG%"   -Q "Backup DataBase %GGG% to disk = '%HHH%\%III%'"
::★★★OSQL -U"sa" -P"sa" -S"127.0.0.1" -d"CircleImage" -Q "Backup DataBase CircleImage to disk = 'c:\111.bak'"
Echo.
Echo.
Echo 恭喜!恭喜!已成功将SQL中的数据库"%GGG%"备份成%HHH%下文件名为"%III%"的文件
Echo.
set CHS=0
pause
cls
goto dosmenu
::============================================================================
:5555
cls
Echo 数据库文件正在还原,在出现还原成功的提示前请您耐心等待……
set XXX=%Temp%\1.sql
Echo.
Echo.
>"%XXX%"   Echo DECLARE @bakFile nvarchar(1024);                      --定义@bakFile       
>>"%XXX%" Echo SET @bakFile = N'%JJJ%';                                       
>>"%XXX%" Echo.                                
>>"%XXX%" Echo DECLARE @restorePath nvarchar(1024);                            
>>"%XXX%" Echo SET @restorePath = N'%KKK%\';                                   
>>"%XXX%" Echo.
>>"%XXX%" Echo DECLARE @dbname nvarchar(128);                                 
>>"%XXX%" Echo SET @dbname = N'%LLL%';                                        
>>"%XXX%" Echo.
>>"%XXX%" Echo DECLARE @filename nvarchar(128);                               
>>"%XXX%" Echo SET @filename = @dbname;                                       
>>"%XXX%" Echo.
>>"%XXX%" Echo CREATE TABLE #LogicalFileBak(LogicalName varchar(255), PhysicalName varchar(255),Type varchar(20), FileGroupName varchar(255), Size varchar(20), MaxSize varchar(20), Fileld VARCHAR(20), CreateLSN VARCHAR(20), DropLSN VARCHAR(20), Uniqueld uniqueidentifier, ReadOnlyLSN VARCHAR(20), ReadWriteLSN VARCHAR(20), BackupSizeInBytes VARCHAR(255), SourceBlockSize VARCHAR(20), FileGroupld VARCHAR(20), LogGroupGUID VARCHAR(20), DifferentialBaseLSN VARCHAR(20), DifferentialBaseGUID uniqueidentifier, IsReadOnly VARCHAR(20), IsPresent VARCHAR(20))       
>>"%XXX%" Echo    --建一个名叫#LogicalFileBak的新表,为什么要建这么多字段的理由见⑤和⑥
>>"%XXX%" Echo.
>>"%XXX%" Echo INSERT #LogicalFileBak EXEC('RESTORE FILELISTONLY FROM DISK = ''' + @bakFile + '''');    --从备份文件中读取逻辑名并存到#LogicalFileBak表中          
>>"%XXX%" Echo.
>>"%XXX%" Echo DECLARE cur CURSOR FOR SELECT LogicalName,Type,FileGroupName FROM #LogicalFileBak;    --定义一个游标cur(相当于数据集)并将搜索结果放到其中             
>>"%XXX%" Echo DECLARE @LogicalName nvarchar(128),@Type char(1),@FileGroupName nvarchar(128);        --定义新变量              
>>"%XXX%" Echo.
>>"%XXX%" Echo DECLARE @cmd nvarchar(4000);                    --定义新变量                                                   
>>"%XXX%" Echo SET @cmd = 'RESTORE DATABASE [' + @dbname + '] FROM DISK = ''' + @bakFile + '''';      --将这一串语句赋给@cmd            
>>"%XXX%" Echo SET @cmd = @cmd + ' WITH REPLACE'                                                      --接着将语句赋给@cmd            
>>"%XXX%" Echo.
>>"%XXX%" Echo OPEN cur;                                --打开游标                                                          
>>"%XXX%" Echo FETCH NEXT FROM cur INTO @LogicalName,@Type,@FileGroupName;             --从这句往下的几句语句用来还原数据库 ,FETCH NEXT表示逐条读取游标中的数据                          
>>"%XXX%" Echo WHILE @@FETCH_STATUS = 0                                                                           
>>"%XXX%" Echo       BEGIN                                                                                         
>>"%XXX%" Echo            SET @cmd = @cmd + ',MOVE ''' + @LogicalName + ''' TO ''' + @restorePath                  
>>"%XXX%" Echo                           + @filename + CASE WHEN @Type = 'D' AND @FileGroupName = 'PRIMARY'        
>>"%XXX%" Echo                                                   THEN '.mdf'                                        
>>"%XXX%" Echo                                               WHEN @Type = 'D' AND @FileGroupName ^<^> 'PRIMARY'     
>>"%XXX%" Echo                                                   THEN '.ndf'                                        
>>"%XXX%" Echo                                               ELSE '_log.ldf'                                        
>>"%XXX%" Echo                                               END + ''''                                             
>>"%XXX%" Echo            FETCH NEXT FROM cur INTO @LogicalName,@Type,@FileGroupName;                               
>>"%XXX%" Echo       END                                                                                            
>>"%XXX%" Echo CLOSE cur;                  --关闭游标                                                                       
>>"%XXX%" Echo DEALLOCATE cur;             --释放游标                                                                     
>>"%XXX%" Echo.
>>"%XXX%" Echo EXEC(@cmd);                                                                                        
>>"%XXX%" Echo.
>>"%XXX%" Echo DROP TABLE #LogicalFileBak;       --删除#LogicalFileBak表                                                               

Osql -U"%EEE%" -P"%FFF%" -i "%XXX%"
del "%XXX%"

Echo.
Echo.
Echo 恭喜!已成功将"%JJJ%"还原成%LLL%,且还原后的文件存放在%KKK%下
Echo.
pause
set CHS=0
cls
goto dosmenu
::============================================================================
:6666
Echo 真的要删除吗?删除后将不可恢复
Echo.
set /P QR=确定删除请按y,放弃删除请按其他键,请选择?    
cls
if /I "%QR%"=="y" (
Echo 正在删除,请等待……
::下面这两句用于清除连接
::>"%Temp%\1.sql" Echo alter database %MMM% set offline with rollback after 1;     
::Osql -U"%EEE%" -P"%FFF%" -i %XXX%
cls
::下面这句开始删除
OSQL -U"%EEE%" -P"%FFF%" -S"127.0.0.1" -Q "Drop DataBase %MMM%"
::其他例子:OSQL -U"sa" -P"sa" -S"127.0.0.1" -Q "Drop DataBase 库名"
del "%Temp%\1.sql"
Echo.
Echo 删除SQL中名为%AAA%的数据库及源文件成功
Echo.
pause
)
set QR=0
set CHS=0
cls
goto dosmenu
::============================================================================
:zzzz
REM 退出
exit


::▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇
::分离数据库的命令:Sp_detach_db 数据库名
::  连接数据库的命令:Sp_attach_db或者sp_attach_single_file_db
::  sp_attach_db [@dbname =] 'dbname', [@filename1 =] 'filename_n' [,...16]
::  sp_attach_single_file_db [@dbname =] 'dbname', [@physname =] 'physical_name'
::
::使用此方法可以正确附加和分离SQL Sever7.0和SQL Server 2000的数据库文件,要点是备份的时候一定要将mdf和ldf两个文件都备份下来,mdf文件是数据库数据文件,ldf是日志文件。


::OSQL -? 显示帮助(具体如下所示)
::用法: osql [-U 登录 ID] [-P 密码]
::[-S 服务器] [-H 主机名] [-E 可信连接]
::[-d 使用数据库名称] [-l 登录超时值] [-t 查询超时值]
::[-h 标题] [-s 列分隔符] [-w 列宽]
::[-a 数据包大小] [-e 回显输入] [-I 允许带引号的标识符]
::[-L 列出服务器] [-c 命令结束] [-D ODBC DSN 名称]
::[-q "命令行查询"] [-Q "命令行查询" 并退出]
::[-n 删除编号方式] [-m 错误级别]
::[-r 发送到 stderr 的消息] [-V 严重级别]
::[-i 输入文件] [-o 输出文件]
::[-p 打印统计信息] [-b 出错时中止批处理]

::①★★★============================================================================================
::可通过下面的语句查询已有备份库的逻辑文件名,以用于 还原数据库语句操作 中的操作
::OSQL -U"sa" -P"sa" -S"127.0.0.1"   -Q "restore filelistonly from disk ='C:\备份的数据库1'"
::
::OSQL -U"sa" -P"sa" -S"127.0.0.1"   -Q "restore filelistonly from disk ='C:\备份的数据库1'" >>C:\1234.txt

::②★★★★★========================================================================================
:: 还原数据库语句操作
::其中的 数据库的逻辑文件名 和 数据库日志的逻辑文件名 是通过上述的语句来查询的

::格式说明:
::osql -E -d CircleImage -Q "restore database 备份后SQL中看到的数据库名 from disk='用于还原的备份文件的路径+文件名' with move '数据库的逻辑文件名' TO '备份后的路径+实际文件名', MOVE '数据库日志的逻辑文件名' TO '备份后的路径+实际文件名'"

::实例:
::OSQL -U"sa" -P"sa" -S"127.0.0.1" -Q "restore database CircleImage from disk='C:\CircleImage备份' with move 'CircleImage_Data' to 'c:\CircleImage.mdf',move ::'CircleImage_Log' to 'c:\CircleImage_log.ldf'"

::上述这么长的语句中切不可出现回车等换行符,且参数的大小写是不可随意更改的

::③★★============================================================================================
:: 更改数据库备份文件逻辑名的方法:

::alter database 数据库名 modify file (name=逻辑名,newname=新逻辑名)

::事实上,上面的语句是更改了sysfiles系统表中的name字段。
::可通过SELECT * FROM sysfiles语句查询本库的sysfiles表的字段,如下:

::fileid groupid     size      maxsize   growth status perf    name         filename
:: 1       1          66264       -1         2560     2         0      jx              D:\
测试用数据\安吉\ForestFireControl_StandingBook.mdf
:: 2       0          1280         -1        2560      66       0     jx_log         D:\
测试用数据\安吉\ForestFireControl_StandingBook_log.ldf
::④★===============================================================================================
::RESTORE FILELISTONLY 语句返回的结果集如果传递到参数呢?请高手指教。

::正常情况下,在查询分析器中   执行  
:: RESTORE   FILELISTONLY   From   disk   =   'path'  
:: 会返回一个结果集。例如:  
:: LogicalName         PhysicalName             Type   FileGroupName         Size        MaxSize    
:: -------------------------------------------------------------------------  
:: Northwind              C:\..\northwnd.mdf        D      PRIMARY               3407872     351843720  
:: Northwind_log       C:\..\northwnd.ldf           L       NULL                    1048576      351843720    
::⑤★================================================================================================
::MS sql server 2000,2005 如何取出restore filelistonly结果集

::            ---------------------------这是SQL SERVER 2000中的原形代码
::            use master
::            go
::            create table #restoreFileList (LogicalName varchar(255), PhysicalName varchar(255),Type varchar(20), FileGroupName varchar(255), Size varchar(20), MaxSize varchar(20) )
::            declare @filename varchar(1000)
::            select @filename = 'e:\svwlx.bak'
::            insert into #restoreFileList execute('restore filelistonly from disk='''+@filename+'''')
::            insert into #restoreFileList execute('restore filelistonly from disk=''e:\svwlx.bak''')
::            select * from #restoreFileList          
::            ---------------------------
::
::            ---------------------------这是SQL SERVER 2005中的原形代码
::            USE [master]
::            GO
::            create table #restoreFileList4 (LogicalName varchar(255), PhysicalName varchar(255),Type varchar(20), FileGroupName varchar(255), Size varchar(20), MaxSize varchar(20), Fileld VARCHAR(20), CreateLSN VARCHAR(20), DropLSN VARCHAR(20), Uniqueld uniqueidentifier, ReadOnlyLSN VARCHAR(20), ReadWriteLSN VARCHAR(20), BackupSizeInBytes VARCHAR(255), SourceBlockSize VARCHAR(20), FileGroupld VARCHAR(20), LogGroupGUID VARCHAR(20), DifferentialBaseLSN VARCHAR(20), DifferentialBaseGUID uniqueidentifier, IsReadOnly VARCHAR(20), IsPresent VARCHAR(20))
::            SELECT * FROM #restoreFileList4
::            insert into #restoreFileList4 execute('restore filelistonly from disk=''d:\Northwind.bak''')
::            SELECT * FROM #restoreFileList4
::⑥★==================================================================================================
::若5555中不添加这么多的字段,则会出现:列名或所提供值的数目与表定义不匹配   的错误
::原因是:
::比如:有个表A,有字段a,b,你在插入表纪录的时候写成
::insert A(a,b) values(xx,xx,xxx)
::表只有2个列,你写了3个值进去,就会出现你描述的错误信息,具体是哪问题,你根据你的环境去检查一下就知道了。

0

在MS SQL Server数据库批量查看表的大小的三种方法

1.查看单表大小:

sp_spaceused '表 '
如果不写表名,就是看整个库的!

2.察看数据库所有表的大小:
 
方法一:内置存储过程法:

EXEC sp_MSforeachtable @command1="print '?'",@command2="sp_spaceused '?'"

方法二:Transact-SQL语句:

--Transact-SQL语句——列表输出
SET NOCOUNT ON
DECLARE @db VARCHAR(20)
--获取当前数据库
SET  @db=db_name()
DBCC  UPDATEUSAGE(@db) WITH NO_INFOMSGS
GO
 
CREATE TABLE #tblSpace
(
数据表名称   varchar(250)   null,
记录笔数   int   null,
保留空间   varchar(15)   null,
数据使用空间   varchar(15)   null,
索引使用空间   varchar(15)   null,
未使用空间   varchar(15)   null
)
DECLARE @tblname varchar(250)
DECLARE curTbls CURSOR FOR
SELECT TABLE_NAME FROM Information_Schema.TABLES
--BASE TABLE很重要
WHERE TABLE_TYPE= 'BASE TABLE '
 
OPEN CurTbls
FETCH NEXT FROM curTbls INTO @tblName
 
WHILE @@FETCH_STATUS=0
BEGIN
INSERT #tblSpace EXEC sp_spaceused @tblName
FETCH NEXT FROM curTbls INTO @tblName
END
CLOSE CurTbls
DEALLOCATE curTbls
 
SELECT * FROM #tblSpace ORDER BY 记录笔数 DESC
 
DROP TABLE #tblSpace

方法三(与方法二类似,但运行效率更高)

 

EXEC sp_MSforeachtable @command1="print '?'",@command2="sp_spaceused '?'"
 
 
create table tmp (name varchar(50),rows int,reserved varchar(50),
 
data varchar(50),index_size varchar(50),unused varchar(50))
 
insert into tmp (name,rows,reserved,
 
data,index_size,unused) exec sp_msforeachTable @Command1="sp_spaceused '?'"--sp_spaceused 't_vehicle'
 
select *,left(data,len(data)-3)  from tmp order by left(data,len(data)-3)/1 desc

 

0

传统零售商“触网”遭遇六大难题

 

  传统零售商“触网”势力越来越强,然而,取得效益者却少之又少。记者昨天获悉,据中国连锁经营协会调查发现,传统零售商开展网络零售存在六大难题,其中成本和盈利难以预期、左右手互搏问题难以解决。

  今年以来,传统零售商频频出手巨资投入“网络世界”:外资零售企业沃尔玛、鞋业巨头百丽国际,本土零售商如广百、广州友谊、华润万家等纷纷投入巨资争相加大开拓网上商城。

  网购市场的庞大消费力吸引众多零售商进军。据中国连锁经营协会介绍,在发展网络零售业务的队伍中,传统零售商的介入作用越来越大,据该协会统计,在2010年连锁百强中,有52家开展了网络零售业务。

  不过,据调查,尽管网络零售业务发展红红火火,但真正取得效益的少之又少,企业上线之后困难重重,主要是存在人才短缺、供应链和物流配送不足、左右手互搏等六大问题,其中左右手互搏、成本和盈利难预期问题最为突出。

 

 

  据中国连锁经营协会有关专家介绍,目前零售商要做电子商务时最纠结之处莫过于:线上虚拟店与线下实体店的冲突。“如果线上线下的价格一样,在网上就太没有竞争力;如果网上的价格要有竞争力,其价格就必须低于线下。这无异于左右手互搏。”该人士还指出,传统零售商开展电子商务将面对价格体系上难以调节和来自供应商的双重价格体系的压力;此外,由于电子商务和实体店铺共同用一个品牌,采取同样的进货渠道,但两者是不同的部门,实行考核的时候两个部门的矛盾也逐渐激化;线上线下送货配合也存在矛盾。

  “成本和盈利很难预期也让传统零售商犹豫”。据介绍,一般而言,如果要建设一个业务覆盖全国、达到亿元销售规模的网络零售业务,初始投入至少在3000万元以上,“目前我国稍有规模的B2C企业的投入,均已达到几亿元、甚至是几十亿元”。而这还仅仅是个开始,具体是否能够盈利,何时盈利,还需要投入多少,基本上都是个未知数。但投资在一家新的卖场,它三年后盈利的可能性很大。

0

当道德遇上不道德

网上又开始热议不见义勇为是不是该入刑。这是一个值得讨论的问题吗?当一个社会需要用法律来约束道德的时候,这是一个国家的悲哀,一个民族的悲哀。

我绝对赞成道德不应该进入法律的范畴。在这个时候应该是我们亲爱的党,我们的国家进行作为的时候!教育、引导,这才是正确之道。为什么会出现这种不作为?不是人们不想作为,是现实不让人们去作为。见义勇为者致伤者不得不过着悲惨的不得温饱的生活,而被见义勇为者有时,虽然有心,但无力时,他不仅背上了不道德的枷锁,连自己的生活也无法保障。如果国家能更多的保障见义勇为者的生活,我相信这种现象可以得到改观!

1/11, 84«1234»
Processed in 0.2897 second(s), 25 queries