下载的sql大全

来源:互联网 发布:高颜值校园青春网络剧 编辑:程序博客网 时间:2024/05/17 03:39
设置内存选项:
SQL code
--设置 min server memory 配置项EXEC sp_configure N'min server memory (MB)', 0--设置 max server memory 配置项EXEC sp_configure N'max server memory (MB)', 256--使更新生效RECONFIGURE WITH OVERRIDE

使用文件及文件组.sql:
SQL code
/*--功能说明 下面的代码是在SQL Server 2000上创建名为 MyDB 的数据库 该数据库包括1个主要数据文件、3个用户定义的文件组和1个日志文件 ALTER DATABASE语句将用户定义文件组指定为默认文件组。 之后,通过指默认的文件组来创建表,并且将图像数据和索引放到指定的文件组中。 最后,将文件组中的指定数据文件删除--*/--切换到 master 数据库USE masterGO--A. 创建数据库 MyDBCREATE DATABASE MyDBON PRIMARY --主文件组和主要数据文件 ( NAME='MyDB_Primary', FILENAME= 'c:/MyDB_Prm.mdf'),FILEGROUP MyDB_FG1 --用户定义文件组1 ( NAME = 'MyDB_FG1_Dat1', FILENAME = 'c:/MyDB_FG1_1.ndf'), --次要数据文件1 ( NAME = 'MyDB_FG1_Dat2', FILENAME = 'd:/MyDB_FG1_2.ndf'), --次要数据文件2FILEGROUP MyDB_FG2 --用户定义文件组2 ( NAME = 'MyDB_FG1_Dat', FILENAME = 'e:/MyDB_FG2.ndf') --次要数据文件LOG ON --日志文件 ( NAME='MyDB_log', FILENAME ='d:/MyDB.ldf')GO--B. 修改默认数据文件组ALTER DATABASE MyDB MODIFY FILEGROUP MyDB_FG1 DEFAULTGO--切换到新建的数据库 MyDBUSE MyDB--C. 在默认文件组MyDB_FG1创建表,并且指定图像数据保存在用户定义文件组MMyDB_FG2CREATE TABLE MyTable ( cola int PRIMARY KEY , colb char(8) , colc image ) TEXTIMAGE_ON MyDB_FG2--在用户定义文件组MyDB_FG2上创建索引CREATE INDEX IX_MyTable ON MyTable(cola) ON MyDB_FG2GO--D. 将要删除数据文件MyDB_FG1_Dat1上的数据转移到其他数据文件中,并且清空数据文件MyDB_FG1_Dat1DBCC SHRINKFILE(MyDB_FG1_Dat1,EMPTYFILE)--删除数据文件MyDB_FG1_Dat1ALTER DATABASE MyDB REMOVE FILE MyDB_FG1_Dat1

调整tempdb数据库的文件属性.sql:
SQL code
--A. 将tempdb数据库的主数据文件大小设置为10MB。ALTER DATABASE tempdbMODIFY FILE( name=tempdev, size=100 MB)GO--B. 将tempdb数据库的主数据文件移动到指定的磁盘分区上,并且为其添加一个数据文件。--移动主数据文件ALTER DATABASE tempdb MODIFY FILE ( NAME='tempdev', FILENAME ='d:/tempdb.mdf')--添加次要数据文件ALTER DATABASE tempdb ADD FILE ( NAME='tempdata_1', FILENAME ='d:/tempdb_data_1.ndf')

日期概念理解中的一些测试.sql:
SQL code
--A. 测试 datetime 精度问题DECLARE @t TABLE(date char(21))INSERT @t SELECT '1900-1-1 00:00:00.000'INSERT @t SELECT '1900-1-1 00:00:00.001'INSERT @t SELECT '1900-1-1 00:00:00.009'INSERT @t SELECT '1900-1-1 00:00:00.002'INSERT @t SELECT '1900-1-1 00:00:00.003'INSERT @t SELECT '1900-1-1 00:00:00.004'INSERT @t SELECT '1900-1-1 00:00:00.005'INSERT @t SELECT '1900-1-1 00:00:00.006'INSERT @t SELECT '1900-1-1 00:00:00.007'INSERT @t SELECT '1900-1-1 00:00:00.008'SELECT date,转换后的日期=CAST(date as datetime) FROM @t/*--结果date 转换后的日期--------------------- --------------------------1900-1-1 00:00:00.000 1900-01-01 00:00:00.0001900-1-1 00:00:00.001 1900-01-01 00:00:00.0001900-1-1 00:00:00.009 1900-01-01 00:00:00.0101900-1-1 00:00:00.002 1900-01-01 00:00:00.0031900-1-1 00:00:00.003 1900-01-01 00:00:00.0031900-1-1 00:00:00.004 1900-01-01 00:00:00.0031900-1-1 00:00:00.005 1900-01-01 00:00:00.0071900-1-1 00:00:00.006 1900-01-01 00:00:00.0071900-1-1 00:00:00.007 1900-01-01 00:00:00.0071900-1-1 00:00:00.008 1900-01-01 00:00:00.007(所影响的行数为 10 行)--*/GO--B. 对于 datetime 类型的纯日期和时间的十六进制表示DECLARE @dt datetime--单纯的日期SET @dt='1900-1-2'SELECT CAST(@dt as binary(8))--结果: 0x0000000100000000--单纯的时间SET @dt='00:00:01'SELECT CAST(@dt as binary(8))--结果: 0x000000000000012CGO--C. 对于 smalldatetime 类型的纯日期和时间的十六进制表示DECLARE @dt smalldatetime--单纯的日期SET @dt='1900-1-2'SELECT CAST(@dt as binary(4))--结果: 0x00010000--单纯的时间SET @dt='00:10'SELECT CAST(@dt as binary(4))--结果: 0x0000000A
CONVERT在日期转换中的使用示例.sql: 
SQL code
--字符转换为日期时,Style的使用--1. Style=101时,表示日期字符串为:mm/dd/yyyy格式SELECT CONVERT(datetime,'11/1/2003',101)--结果:2003-11-01 00:00:00.000--2. Style=101时,表示日期字符串为:dd/mm/yyyy格式SELECT CONVERT(datetime,'11/1/2003',103)--结果:2003-01-11 00:00:00.000/*== 日期转换为字符串 ==*/DECLARE @dt datetimeSET @dt='2003-1-11'--1. Style=101时,表示将日期转换为:mm/dd/yyyy 格式SELECT CONVERT(varchar,@dt,101)--结果:01/11/2003--2. Style=103时,表示将日期转换为:dd/mm/yyyy 格式SELECT CONVERT(varchar,@dt,103)--结果:11/01/2003/*== 这是很多人经常犯的错误,对非日期型转换使用日期的style样式 ==*/SELECT CONVERT(varchar,'2003-1-11',101)--结果:2003-1-11

SET DATEFORMAT对日期处理的影响.sql
SQL code
--1./*--说明 SET DATEFORMAT设置对使用CONVERT把字符型日期转换为日期的处理也具有影响 但不影响明确指定了style的CONVERT处理。--*/--示例 ,在下面的示例中,第一个CONVERT转换未指定style,转换的结果受SET DATAFORMAT的影响,第二个CONVERT转换指定了style,转换结果受style的影响。--设置输入日期顺序为 日/月/年SET DATEFORMAT DMY--不指定Style参数的CONVERT转换将受到SET DATEFORMAT的影响SELECT CONVERT(datetime,'2-1-2005')--结果: 2005-01-02 00:00:00.000--指定Style参数的CONVERT转换不受SET DATEFORMAT的影响SELECT CONVERT(datetime,'2-1-2005',101)--结果: 2005-02-01 00:00:00.000GO--2./*--说明 如果输入的日期包含了世纪部分,则对日期进行解释处理时 年份的解释不受SET DATEFORMAT设置的影响。--*/--示例,在下面的代码中,同样的SET DATEFORMAT设置,输入日期的世纪部分与不输入日期的世纪部分,解释的日期结果不同。DECLARE @dt datetime--设置SET DATEFORMAT为:月日年SET DATEFORMAT MDY--输入的日期中指定世纪部分SET @dt='01-2002-03'SELECT @dt--结果: 2002-01-03 00:00:00.000--输入的日期中不指定世纪部分SET @dt='01-02-03'SELECT @dt--结果: 2003-01-02 00:00:00.000GO--3./*--说明 如果输入的日期不包含日期分隔符,那么SQL Server在对日期进行解释时 将忽略SET DATEFORMAT的设置。--*/--示例,在下面的代码中,不包含日期分隔符的字符日期,在不同的SET DATEFORMAT设置下,其解释的结果是一样的。DECLARE @dt datetime--设置SET DATEFORMAT为:月日年SET DATEFORMAT MDYSET @dt='010203'SELECT @dt--结果: 2001-02-03 00:00:00.000--设置SET DATEFORMAT为:日月年SET DATEFORMAT DMYSET @dt='010203'SELECT @dt--结果: 2001-02-03 00:00:00.000--输入的日期中包含日期分隔符SET @dt='01-02-03'SELECT @dt--结果: 2003-02-01 00:00:00.000

SET LANGUAGE对日期处理的影响示例.sql
SQL code
--以下示例演示了在不同的语言环境(SET LANGUAGE)下,DATENAME与CONVERT函数的不同结果。USE master--设置会话的语言环境为: EnglishSET LANGUAGE N'English'SELECT DATENAME(Month,GETDATE()) AS [Month], DATENAME(Weekday,GETDATE()) AS [Weekday], CONVERT(varchar,GETDATE(),109) AS [CONVERT]/*--结果:Month Weekday CONVERT------------- -------------- -------------------------------March Tuesday Mar 15 2005 8:59PM--*/--设置会话的语言环境为: 简体中文SET LANGUAGE N'简体中文'SELECT DATENAME(Month,GETDATE()) AS [Month], DATENAME(Weekday,GETDATE()) AS [Weekday], CONVERT(varchar,GETDATE(),109) AS [CONVERT]/*--结果Month Weekday CONVERT------------- --------------- -----------------------------------------05 星期四 05 19 2005 2:49:20:607PM--*/

日期格式化处理.sql
SQL code
DECLARE @dt datetimeSET @dt=GETDATE()--1.短日期格式:yyyy-m-dSELECT REPLACE(CONVERT(varchar(10),@dt,120),N'-0','-')--2.长日期格式:yyyy年mm月dd日 --A. 方法1 SELECT STUFF(STUFF(CONVERT(char(8),@dt,112),5,0,N''),8,0,N'')+N''--B. 方法2 SELECT DATENAME(Year,@dt)+N''+DATENAME(Month,@dt)+N''+DATENAME(Day,@dt)+N''--3.长日期格式:yyyy年m月d日SELECT DATENAME(Year,@dt)+N''+CAST(DATEPART(Month,@dt) AS varchar)+N''+DATENAME(Day,@dt)+N''--4.完整日期+时间格式:yyyy-mm-dd hh:mi:ss:mmmSELECT CONVERT(char(11),@dt,120)+CONVERT(char(12),@dt,114)

日期推算处理.sql
SQL code
DECLARE @dt datetimeSET @dt=GETDATE()DECLARE @number intSET @number=3--1.指定日期该年的第一天或最后一天--A. 年的第一天SELECT CONVERT(char(5),@dt,120)+'1-1'--B. 年的最后一天SELECT CONVERT(char(5),@dt,120)+'12-31'--2.指定日期所在季度的第一天或最后一天--A. 季度的第一天SELECT CONVERT(datetime, CONVERT(char(8), DATEADD(Month, DATEPART(Quarter,@dt)*3-Month(@dt)-2, @dt), 120)+'1')--B. 季度的最后一天(CASE判断法)SELECT CONVERT(datetime, CONVERT(char(8), DATEADD(Month, DATEPART(Quarter,@dt)*3-Month(@dt), @dt), 120) +CASE WHEN DATEPART(Quarter,@dt) in(1,4) THEN '31'ELSE '30' END)--C. 季度的最后一天(直接推算法)SELECT DATEADD(Day,-1, CONVERT(char(8), DATEADD(Month, 1+DATEPART(Quarter,@dt)*3-Month(@dt), @dt), 120)+'1')--3.指定日期所在月份的第一天或最后一天--A. 月的第一天SELECT CONVERT(datetime,CONVERT(char(8),@dt,120)+'1')--B. 月的最后一天SELECT DATEADD(Day,-1,CONVERT(char(8),DATEADD(Month,1,@dt),120)+'1')--C. 月的最后一天(容易使用的错误方法)SELECT DATEADD(Month,1,DATEADD(Day,-DAY(@dt),@dt))--4.指定日期所在周的任意一天SELECT DATEADD(Day,@number-DATEPART(Weekday,@dt),@dt)--5.指定日期所在周的任意星期几--A. 星期天做为一周的第1天SELECT DATEADD(Day,@number-(DATEPART(Weekday,@dt)+@@DATEFIRST-1)%7,@dt)--B. 星期一做为一周的第1天SELECT DATEADD(Day,@number-(DATEPART(Weekday,@dt)+@@DATEFIRST-2)%7-1,@dt)
特殊日期加减函数.sql 
SQL code
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_DateADD]') and xtype in (N'FN', N'IF', N'TF')) drop function [dbo].[f_DateADD]GO/*--特殊日期加减函数 对于日期指定部分的加减,使用DATEADD函数就可以轻松实现。 在实际的处理中,还有一种比较另类的日期加减处理 就是在指定的日期中,加上(或者减去)多个日期部分 比如将2005年3月11日,加上1年3个月11天2小时。 对于这种日期的加减处理,DATEADD函数的力量就显得有点不够。 本函数实现这样格式的日期字符串加减处理: y-m-d h:m:s.m | -y-m-d h:m:s.m 说明: 要加减的日期字符输入方式与日期字符串相同。日期与时间部分用空格分隔 最前面一个字符如果是减号(-)的话,表示做减法处理,否则做加法处理。 如果日期字符只包含数字,则视为日期字符中,仅包含天的信息。--*//*--调用示例 SELECT dbo.f_DateADD(GETDATE(),'11:10')--*/CREATE FUNCTION dbo.f_DateADD(@Date datetime,@DateStr varchar(23))RETURNS datetimeASBEGIN DECLARE @bz int,@s varchar(12),@i int IF @DateStr IS NULL OR @Date IS NULL OR(CHARINDEX('.',@DateStr)>0 AND @DateStr NOT LIKE '%[:]%[:]%.%') RETURN(NULL) IF @DateStr='' RETURN(@Date) SELECT @bz=CASE WHEN LEFT(@DateStr,1)='-' THEN -1 ELSE 1 END, @DateStr=CASE WHEN LEFT(@Date,1)='-' THEN STUFF(RTRIM(LTRIM(@DateStr)),1,1,'') ELSE RTRIM(LTRIM(@DateStr)) END IF CHARINDEX(' ',@DateStr)>1 OR CHARINDEX('-',@DateStr)>1 OR(CHARINDEX('.',@DateStr)=0 AND CHARINDEX(':',@DateStr)=0) BEGIN SELECT @i=CHARINDEX(' ',@DateStr+' ') ,@s=REVERSE(LEFT(@DateStr,@i-1))+'-' ,@DateStr=STUFF(@DateStr,1,@i,'') ,@i=0 WHILE @s>'' and @i<3 SELECT @Date=CASE @i WHEN 0 THEN DATEADD(Day,@bz*REVERSE(LEFT(@s,CHARINDEX('-',@s)-1)),@Date) WHEN 1 THEN DATEADD(Month,@bz*REVERSE(LEFT(@s,CHARINDEX('-',@s)-1)),@Date) WHEN 2 THEN DATEADD(Year,@bz*REVERSE(LEFT(@s,CHARINDEX('-',@s)-1)),@Date) END, @s=STUFF(@s,1,CHARINDEX('-',@s),''), @i=@i+1 END IF @DateStr>'' BEGIN IF CHARINDEX('.',@DateStr)>0 SELECT @Date=DATEADD(Millisecond ,@bz*STUFF(@DateStr,1,CHARINDEX('.',@DateStr),''), @Date), @DateStr=LEFT(@DateStr,CHARINDEX('.',@DateStr)-1)+':', @i=0 ELSE SELECT @DateStr=@DateStr+':',@i=0 WHILE @DateStr>'' and @i<3 SELECT @Date=CASE @i WHEN 0 THEN DATEADD(Hour,@bz*LEFT(@DateStr,CHARINDEX(':',@DateStr)-1),@Date) WHEN 1 THEN DATEADD(Minute,@bz*LEFT(@DateStr,CHARINDEX(':',@DateStr)-1),@Date) WHEN 2 THEN DATEADD(Second,@bz*LEFT(@DateStr,CHARINDEX(':',@DateStr)-1),@Date) END, @DateStr=STUFF(@DateStr,1,CHARINDEX(':',@DateStr),''), @i=@i+1 END RETURN(@Date)ENDGO

查询指定日期段内过生日的人员.sql
SQL code
--测试数据DECLARE @t TABLE(ID int,Name varchar(10),Birthday datetime)INSERT @t SELECT 1,'aa','1999-01-01'UNION ALL SELECT 2,'bb','1996-02-29'UNION ALL SELECT 3,'bb','1934-03-01'UNION ALL SELECT 4,'bb','1966-04-01'UNION ALL SELECT 5,'bb','1997-05-01'UNION ALL SELECT 6,'bb','1922-11-21'UNION ALL SELECT 7,'bb','1989-12-11'DECLARE @dt1 datetime,@dt2 datetime--查询 2003-12-05 至 2004-02-28 生日的记录SELECT @dt1='2003-12-05',@dt2='2004-02-28'SELECT * FROM @tWHERE DATEADD(Year,DATEDIFF(Year,Birthday,@dt1),Birthday) BETWEEN @dt1 AND @dt2 OR DATEADD(Year,DATEDIFF(Year,Birthday,@dt2),Birthday) BETWEEN @dt1 AND @dt2/*--结果ID Name Birthday---------------- ---------------- --------------------------1 aa 1999-01-01 00:00:00.0007 bb 1989-12-11 00:00:00.000--*/--查询 2003-12-05 至 2006-02-28 生日的记录SET @dt2='2006-02-28'SELECT * FROM @tWHERE DATEADD(Year,DATEDIFF(Year,Birthday,@dt1),Birthday) BETWEEN @dt1 AND @dt2 OR DATEADD(Year,DATEDIFF(Year,Birthday,@dt2),Birthday) BETWEEN @dt1 AND @dt2/*--查询结果ID Name Birthday---------------- ----------------- --------------------------1 aa 1999-01-01 00:00:00.0002 bb 1996-02-29 00:00:00.0007 bb 1989-12-11 00:00:00.000--*/

生成日期列表的函数.sql
SQL code
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_getdate]') and xtype in (N'FN', N'IF', N'TF'))drop function [dbo].[f_getdate]GO/*--生成日期列表 生成指定年份的工作日/休息日列表--邹建 2003.12(引用请保留此信息)--*//*--调用示例 --查询 2003 年的工作日列表 SELECT * FROM dbo.f_getdate(2003,0) --查询 2003 年的休息日列表 SELECT * FROM dbo.f_getdate(2003,1) --查询 2003 年全部日期列表 SELECT * FROM dbo.f_getdate(2003,NULL)--*/CREATE FUNCTION dbo.f_getdate(@year int, --要查询的年份@bz bit --@bz=0 查询工作日,@bz=1 查询休息日,@bz IS NULL 查询全部日期)RETURNS @re TABLE(id int identity(1,1),Date datetime,Weekday nvarchar(3))ASBEGIN DECLARE @tb TABLE(ID int IDENTITY(0,1),Date datetime) INSERT INTO @tb(Date) SELECT TOP 366 DATEADD(Year,@YEAR-1900,'1900-1-1') FROM sysobjects a ,sysobjects b UPDATE @tb SET Date=DATEADD(DAY,id,Date) DELETE FROM @tb WHERE Date>DATEADD(Year,@YEAR-1900,'1900-12-31') IF @bz=0 INSERT INTO @re(Date,Weekday) SELECT Date,DATENAME(Weekday,Date) FROM @tb WHERE (DATEPART(Weekday,Date)+@@DATEFIRST-1)%7 BETWEEN 1 AND 5 ELSE IF @bz=1 INSERT INTO @re(Date,Weekday) SELECT Date,DATENAME(Weekday,Date) FROM @tb WHERE (DATEPART(Weekday,Date)+@@DATEFIRST-1)%7 IN (0,6) ELSE INSERT INTO @re(Date,Weekday) SELECT Date,DATENAME(Weekday,Date) FROM @tb RETURNENDGO/*====================================================================*/if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_getdate]') and xtype in (N'FN', N'IF', N'TF'))drop function [dbo].[f_getdate]GO/*--生成列表 生成指定日期段的日期列表--邹建 2005.03(引用请保留此信息)--*//*--调用示例 --查询工作日 SELECT * FROM dbo.f_getdate('2005-1-3','2005-4-5',0) --查询休息日 SELECT * FROM dbo.f_getdate('2005-1-3','2005-4-5',1) --查询全部日期 SELECT * FROM dbo.f_getdate('2005-1-3','2005-4-5',NULL)--*/CREATE FUNCTION dbo.f_getdate(@begin_date Datetime, --要查询的开始日期@end_date Datetime, --要查询的结束日期@bz bit --@bz=0 查询工作日,@bz=1 查询休息日,@bz IS NULL 查询全部日期)RETURNS @re TABLE(id int identity(1,1),Date datetime,Weekday nvarchar(3))ASBEGIN DECLARE @tb TABLE(ID int IDENTITY(0,1),a bit) INSERT INTO @tb(a) SELECT TOP 366 0 FROM sysobjects a ,sysobjects b IF @bz=0 WHILE @begin_date<=@end_date BEGIN INSERT INTO @re(Date,Weekday) SELECT Date,DATENAME(Weekday,Date) FROM( SELECT Date=DATEADD(Day,ID,@begin_date) FROM @tb )a WHERE Date<=@end_date AND (DATEPART(Weekday,Date)+@@DATEFIRST-1)%7 BETWEEN 1 AND 5 SET @begin_date=DATEADD(Day,366,@begin_date) END ELSE IF @bz=1 WHILE @begin_date<=@end_date BEGIN INSERT INTO @re(Date,Weekday) SELECT Date,DATENAME(Weekday,Date) FROM( SELECT Date=DATEADD(Day,ID,@begin_date) FROM @tb )a WHERE Date<=@end_date AND (DATEPART(Weekday,Date)+@@DATEFIRST-1)%7 in(0,6) SET @begin_date=DATEADD(Day,366,@begin_date) END ELSE WHILE @begin_date<=@end_date BEGIN INSERT INTO @re(Date,Weekday) SELECT Date,DATENAME(Weekday,Date) FROM( SELECT Date=DATEADD(Day,ID,@begin_date) FROM @tb )a WHERE Date<=@end_date SET @begin_date=DATEADD(Day,366,@begin_date) END RETURNENDGO
工作日处理函数(标准节假日).sql 
SQL code
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkDay]') and xtype in (N'FN', N'IF', N'TF'))drop function [dbo].[f_WorkDay]GO--计算两个日期相差的工作天数CREATE FUNCTION f_WorkDay(@dt_begin datetime, --计算的开始日期@dt_end datetime --计算的结束日期)RETURNS intASBEGIN DECLARE @workday int,@i int,@bz bit,@dt datetime IF @dt_begin>@dt_end SELECT @bz=1,@dt=@dt_begin,@dt_begin=@dt_end,@dt_end=@dt ELSE SET @bz=0 SELECT @i=DATEDIFF(Day,@dt_begin,@dt_end)+1, @workday=@i/7*5, @dt_begin=DATEADD(Day,@i/7*7,@dt_begin) WHILE @dt_begin<=@dt_end BEGIN SELECT @workday=CASE WHEN (@@DATEFIRST+DATEPART(Weekday,@dt_begin)-1)%7 BETWEEN 1 AND 5 THEN @workday+1 ELSE @workday END, @dt_begin=@dt_begin+1 END RETURN(CASE WHEN @bz=1 THEN -@workday ELSE @workday END)ENDGO/*=================================================================*/if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkDayADD]') and xtype in (N'FN', N'IF', N'TF'))drop function [dbo].[f_WorkDayADD]GO--在指定日期上,增加指定工作天数后的日期CREATE FUNCTION f_WorkDayADD(@date datetime, --基础日期@workday int --要增加的工作日数)RETURNS datetimeASBEGIN DECLARE @bz int --增加整周的天数 SELECT @bz=CASE WHEN @workday<0 THEN -1 ELSE 1 END ,@date=DATEADD(Week,@workday/5,@date) ,@workday=@workday%5 --增加不是整周的工作天数 WHILE @workday<>0 SELECT @date=DATEADD(Day,@bz,@date), @workday=CASE WHEN (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 BETWEEN 1 AND 5 THEN @workday-@bz ELSE @workday END --避免处理后的日期停留在非工作日上 WHILE (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 in(0,6) SET @date=DATEADD(Day,@bz,@date) RETURN(@date)END

工作日处理函数(自定义节假日).sql
SQL code
if exists (select * from dbo.sysobjects where id = object_id(N'[tb_Holiday]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [tb_Holiday]GO--定义节假日表CREATE TABLE tb_Holiday(HDate smalldatetime primary key clustered, --节假日期Name nvarchar(50) not null) --假日名称GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkDay]') and xtype in (N'FN', N'IF', N'TF'))drop function [dbo].[f_WorkDay]GO--计算两个日期之间的工作天数CREATE FUNCTION f_WorkDay(@dt_begin datetime, --计算的开始日期@dt_end datetime --计算的结束日期)RETURNS intASBEGIN IF @dt_begin>@dt_end RETURN(DATEDIFF(Day,@dt_begin,@dt_end) +1-( SELECT COUNT(*) FROM tb_Holiday WHERE HDate BETWEEN @dt_begin AND @dt_end)) RETURN(-(DATEDIFF(Day,@dt_end,@dt_begin) +1-( SELECT COUNT(*) FROM tb_Holiday WHERE HDate BETWEEN @dt_end AND @dt_begin)))ENDGOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkDayADD]') and xtype in (N'FN', N'IF', N'TF'))drop function [dbo].[f_WorkDayADD]GO--在指定日期上增加工作天数CREATE FUNCTION f_WorkDayADD(@date datetime, --基础日期@workday int --要增加的工作日数)RETURNS datetimeASBEGIN IF @workday>0 WHILE @workday>0 SELECT @date=@date+@workday,@workday=count(*) FROM tb_Holiday WHERE HDate BETWEEN @date AND @date+@workday ELSE WHILE @workday<0 SELECT @date=@date+@workday,@workday=-count(*) FROM tb_Holiday WHERE HDate BETWEEN @date AND @date+@workday RETURN(@date)END

计算工作时间的函数.sql
SQL code
if exists (select * from dbo.sysobjects where id = object_id(N'[tb_worktime]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [tb_worktime]GO--定义工作时间表CREATE TABLE tb_worktime( ID int identity(1,1) PRIMARY KEY, --序号 time_start smalldatetime, --工作的开始时间 time_end smalldatetime, --工作的结束时间 worktime AS DATEDIFF(Minute,time_start,time_end) --工作时数(分钟))GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkTime]') and xtype in (N'FN', N'IF', N'TF'))drop function [dbo].[f_WorkTime]GO--计算两个日期之间的工作时间CREATE FUNCTION f_WorkTime(@date_begin datetime, --计算的开始时间@date_end datetime --计算的结束时间)RETURNS intASBEGIN DECLARE @worktime int IF DATEDIFF(Day,@date_begin,@date_end)=0 SELECT @worktime=SUM(DATEDIFF(Minute, CASE WHEN CONVERT(VARCHAR,@date_begin,108)>time_start THEN CONVERT(VARCHAR,@date_begin,108) ELSE time_start END, CASE WHEN CONVERT(VARCHAR,@date_end,108)<time_end THEN CONVERT(VARCHAR,@date_end,108) ELSE time_end END)) FROM tb_worktime WHERE time_end>CONVERT(VARCHAR,@date_begin,108) AND time_start<CONVERT(VARCHAR,@date_end,108) ELSE SET @worktime =(SELECT SUM(CASE WHEN CONVERT(VARCHAR,@date_begin,108)>time_start THEN DATEDIFF(Minute,CONVERT(VARCHAR,@date_begin,108),time_end) ELSE worktime END) FROM tb_worktime WHERE time_end>CONVERT(VARCHAR,@date_begin,108)) +(SELECT SUM(CASE WHEN CONVERT(VARCHAR,@date_end,108)<time_end THEN DATEDIFF(Minute,time_start,CONVERT(VARCHAR,@date_end,108)) ELSE worktime END) FROM tb_worktime WHERE time_start<CONVERT(VARCHAR,@date_end,108)) +CASE WHEN DATEDIFF(Day,@date_begin,@date_end)>1 THEN (DATEDIFF(Day,@date_begin,@date_end)-1) *(SELECT SUM(worktime) FROM tb_worktime) ELSE 0 END RETURN(@worktime)END
原创粉丝点击