sql大全(一)

sql大全(一)

都是写好的实用sql, 直接拿来使用吧。

 

总纲:

1.   设置内存选项

2.   实用文件及文件组

3.   调整temp数据库的文件属性

4.   日期概念理解中的一些测试

5.   CINVERT在日期转换中的使用示例

6.   SET DATEFORMAT对日期处理的影响

7.   SET LANGUAGE对日期处理的影响示例

8.   日期格式化处理

9.   日期推算处理

10. 特殊日期加减函数

11.查询指定日期段内过生日的人员

12.生成日期列表的函数

 

1.设置内存选项

--设置 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

 

2.使用文件及文件组

*--功能说明

    下面的代码是在SQL Server 2000上创建名为 MyDB 的数据库
    该数据库包括1个主要数据文件、3个用户定义的文件组和1个日志文件
    ALTER DATABASE语句将用户定义文件组指定为默认文件组。
    之后,通过指默认的文件组来创建表,并且将图像数据和索引放到指定的文件组中。
    最后,将文件组中的指定数据文件删除
--*/

--切换到 master 数据库
USE master
GO

--A. 创建数据库 MyDB
CREATE DATABASE MyDB
ON 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'),  --次要数据文件2
FILEGROUP 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 DEFAULT
GO

--切换到新建的数据库 MyDB
USE MyDB

--C. 在默认文件组MyDB_FG1创建表,并且指定图像数据保存在用户定义文件组MMyDB_FG2
CREATE 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_FG2
GO


--D. 将要删除数据文件MyDB_FG1_Dat1上的数据转移到其他数据文件中,并且清空数据文件MyDB_FG1_Dat1
DBCC SHRINKFILE(MyDB_FG1_Dat1,EMPTYFILE)
--删除数据文件MyDB_FG1_Dat1
ALTER DATABASE MyDB REMOVE FILE MyDB_FG1_Dat1


调整tempdb数据库的文件属性.sql:
SQL code
--A. 将tempdb数据库的主数据文件大小设置为10MB。
ALTER DATABASE tempdb
MODIFY 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')

 

3.调整tempdb数据库的文件属性

--A. 将tempdb数据库的主数据文件大小设置为10MB。
ALTER DATABASE tempdb
MODIFY 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')

 

4.日期概念理解中的一些测试

--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.000
1900-1-1 00:00:00.001 1900-01-01 00:00:00.000
1900-1-1 00:00:00.009 1900-01-01 00:00:00.010
1900-1-1 00:00:00.002 1900-01-01 00:00:00.003
1900-1-1 00:00:00.003 1900-01-01 00:00:00.003
1900-1-1 00:00:00.004 1900-01-01 00:00:00.003
1900-1-1 00:00:00.005 1900-01-01 00:00:00.007
1900-1-1 00:00:00.006 1900-01-01 00:00:00.007
1900-1-1 00:00:00.007 1900-01-01 00:00:00.007
1900-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))
--结果: 0x000000000000012C
GO

--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

 

5.CONVERT在日期转换中的使用示例

--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.000
GO

--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.000
GO

--3.
/*--说明

    如果输入的日期不包含日期分隔符,那么SQL Server在对日期进行解释时
    将忽略SET DATEFORMAT的设置。
--*/

--示例,在下面的代码中,不包含日期分隔符的字符日期,在不同的SET DATEFORMAT设置下,其解释的结果是一样的。
DECLARE @dt datetime

--设置SET DATEFORMAT为:月日年
SET DATEFORMAT MDY
SET @dt='010203'
SELECT @dt
--结果: 2001-02-03 00:00:00.000

--设置SET DATEFORMAT为:日月年
SET DATEFORMAT DMY
SET @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

 

6.SET DATEFORMAT对日期处理的影响

--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.000
GO

--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.000
GO

--3.
/*--说明

    如果输入的日期不包含日期分隔符,那么SQL Server在对日期进行解释时
    将忽略SET DATEFORMAT的设置。
--*/

--示例,在下面的代码中,不包含日期分隔符的字符日期,在不同的SET DATEFORMAT设置下,其解释的结果是一样的。
DECLARE @dt datetime

--设置SET DATEFORMAT为:月日年
SET DATEFORMAT MDY
SET @dt='010203'
SELECT @dt
--结果: 2001-02-03 00:00:00.000

--设置SET DATEFORMAT为:日月年
SET DATEFORMAT DMY
SET @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

 

7.SET LANGUAGE对日期处理的影响示例

--以下示例演示了在不同的语言环境(SET LANGUAGE)下,DATENAME与CONVERT函数的不同结果。
USE master

--设置会话的语言环境为: English
SET 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
--*/

 

8.日期格式化处理

DECLARE @dt datetime
SET @dt=GETDATE()

--1.短日期格式:yyyy-m-d
SELECT 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:mmm
SELECT CONVERT(char(11),@dt,120)+CONVERT(char(12),@dt,114)

 

9.日期推算处理

DECLARE @dt datetime
SET @dt=GETDATE()

DECLARE @number int
SET @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)

 

10.特殊日期加减函数

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 datetime
AS
BEGIN
    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)
END
GO

 

11.查询指定日期段内过生日的人

--测试数据
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 @t
WHERE 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.000
7           bb         1989-12-11 00:00:00.000
--*/

--查询 2003-12-05 至 2006-02-28 生日的记录
SET @dt2='2006-02-28'
SELECT * FROM @t
WHERE 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.000
2           bb         1996-02-29 00:00:00.000
7           bb         1989-12-11 00:00:00.000
--*/

 

12.生成日期列表的函数

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))
AS
BEGIN
    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
        
    RETURN
END
GO


/*====================================================================*/

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))
AS
BEGIN
    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

    RETURN
END
GO
posted @ 2010-09-05 20:24  梦想(胡大利)  阅读(213)  评论(0编辑  收藏  举报