zoukankan      html  css  js  c++  java
  • SQL经典案例

    查询表内容
    SELECT
    表名=case when a.colorder=1 then d.name else '' end,
    表说明=case when a.colorder=1 then isnull(f.value,'') else '' end,
    字段序号=a.colorder,
    字段名=a.name,
    标识=case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then '√'else '' end,
    主键=case when exists(SELECT 1 FROM sysobjects where xtype='PK' and name in (
    SELECT name FROM sysindexes WHERE indid in(
    SELECT indid FROM sysindexkeys WHERE id = a.id AND colid=a.colid
    ))) then '√' else '' end,
    类型=b.name,
    占用字节数=a.length,
    长度=COLUMNPROPERTY(a.id,a.name,'PRECISION'),
    小数位数=isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0),
    允许空=case when a.isnullable=1 then '√'else '' end,
    默认值=isnull(e.text,''),
    字段说明=isnull(g.[value],'')
    FROM syscolumns a
    left join systypes b on a.xtype=b.xusertype
    inner join sysobjects d on a.id=d.id and d.xtype='U' and d.name<>'dtproperties'
    left join syscomments e on a.cdefault=e.id
    left join sysproperties g on a.id=g.id and a.colid=g.smallid
    left join sysproperties f on d.id=f.id and f.smallid=0
    --where d.name='要查询的表' --如果只查询指定表,加上此条件
    order by a.id,a.colorder
    ========================================================
    SQL交*表实例
    很简单的一个东西,见网上好多朋友问“怎么实现交*表?”,以下是我写的一个例子,数据库基于SQL SERVER 2000。
    建表:
    在查询分析器里运行:
    CREATE TABLE [Test] (
    [id] [int] IDENTITY (1, 1) NOT NULL ,
    [name] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
    [subject] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
    [Source] [numeric](18, 0) NULL
    ) ON [PRIMARY]
    GO
    INSERT INTO [test] ([name],[subject],[Source]) values (N'张三',N'语文',60)
    INSERT INTO [test] ([name],[subject],[Source]) values (N'李四',N'数学',70)
    INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'英语',80)
    INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'数学',75)
    INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'语文',57)
    INSERT INTO [test] ([name],[subject],[Source]) values (N'李四',N'语文',80)
    INSERT INTO [test] ([name],[subject],[Source]) values (N'张三',N'英语',100)
    Go

    交*表语句的实现:
    --用于:交*表的列数是确定的
    select name,sum(case subject when '数学' then source else 0 end) as '数学',
    sum(case subject when '英语' then source else 0 end) as '英语',
    sum(case subject when '语文' then source else 0 end) as '语文'
    from test
    group by name

    --用于:交*表的列数是不确定的

    declare @sql varchar(8000)
    set @sql = 'select name,'
    select @sql = @sql + 'sum(case subject when '''+subject+'''
    then source else 0 end) as '''+subject+''','
    from (select distinct subject from test) as a
    select @sql = left(@sql,len(@sql)-1) + ' from test group by name'
    exec(@sql)
    go
    ================================================================================
    SQL Server 存储过程的分页方案比拼
    出处

    SQL Server 存储过程的分页,这个问题已经讨论过几年了,很多朋友在问我,所以在此发表一下我的观点
    建立表:

    CREATE TABLE [TestTable] (
    [ID] [int] IDENTITY (1, 1) NOT NULL ,
    [FirstName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,
    [LastName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,
    [Country] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
    [Note] [nvarchar] (2000) COLLATE Chinese_PRC_CI_AS NULL
    ) ON [PRIMARY]
    GO

    插入数据:(2万条,用更多的数据测试会明显一些)
    SET IDENTITY_INSERT TestTable ON

    declare @i int
    set @i=1
    while @i<=20000
    begin
    insert into TestTable([id], FirstName, LastName, Country,Note) values(@i, 'FirstName_XXX','LastName_XXX','Country_XXX','Note_XXX')
    set @i=@i+1
    end

    SET IDENTITY_INSERT TestTable OFF

    -------------------------------------

    分页方案一:(利用Not In和SELECT TOP分页)
    语句形式:
    SELECT TOP 10 *
    FROM TestTable
    WHERE (ID NOT IN
    (SELECT TOP 20 id
    FROM TestTable
    ORDER BY id))
    ORDER BY ID

    SELECT TOP 页大小 *
    FROM TestTable
    WHERE (ID NOT IN
    (SELECT TOP 页大小*页数 id
    FROM 表
    ORDER BY id))
    ORDER BY ID
    -------------------------------------
    分页方案二:(利用ID大于多少和SELECT TOP分页)
    语句形式:
    SELECT TOP 10 *
    FROM TestTable
    WHERE (ID >
    (SELECT MAX(id)
    FROM (SELECT TOP 20 id
    FROM TestTable
    ORDER BY id) AS T))
    ORDER BY ID

    SELECT TOP 页大小 *
    FROM TestTable
    WHERE (ID >
    (SELECT MAX(id)
    FROM (SELECT TOP 页大小*页数 id
    FROM 表
    ORDER BY id) AS T))
    ORDER BY ID

    -------------------------------------
    分页方案三:(利用SQL的游标存储过程分页)
    create procedure XiaoZhengGe
    @sqlstr nvarchar(4000), --查询字符串
    @currentpage int, --第N页
    @pagesize int --每页行数
    as
    set nocount on
    declare @P1 int, --P1是游标的id
    @rowcount int
    exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount output
    select ceiling(1.0*@rowcount/@pagesize) as 总页数--,@rowcount as 总行数,@currentpage as 当前页
    set @currentpage=(@currentpage-1)*@pagesize+1
    exec sp_cursorfetch @P1,16,@currentpage,@pagesize
    exec sp_cursorclose @P1
    set nocount off
    其它的方案:如果没有主键,可以用临时表,也可以用方案三做,但是效率会低。
    建议优化的时候,加上主键和索引,查询效率会提高。

    通过SQL 查询分析器,显示比较:我的结论是:
    分页方案二:(利用ID大于多少和SELECT TOP分页)效率最高,需要拼接SQL语句
    分页方案一:(利用Not In和SELECT TOP分页) 效率次之,需要拼接SQL语句
    分页方案三:(利用SQL的游标存储过程分页) 效率最差,但是最为通用
    在实际情况中,要具体分析。
    ====================================================================================
    得到随机排序结果
    出处

    SELECT *
    FROM Northwind..Orders
    ORDER BY NEWID()

    SELECT TOP 10 *
    FROM Northwind..Orders
    ORDER BY NEWID()
    ====================================================================================
    select
    to_char(日期,'yyyymmdd') DATE_ID,to_char(日期,'yyyy')||'年'||to_char(日期,'mm')||'月'||to_char(日期,'dd')||'日' DATE_NAME,
    to_char(日期,'yyyymm') MONTH_ID,to_char(日期,'yyyy')||'年'||to_char(日期,'mm')||'月' MONTH_NAME,
    'Q'||to_char(日期,'q.yyyy') QUARTERID,to_char(日期,'yyyy')||'年第'||to_char(日期,'q')||'季度' QUARTERID_NAME,
    to_char(日期,'yyyy') YEAR_ID,to_char(日期,'yyyy')||'年' YEAR_NAME
    from(
    select to_date('2000-01-01','yyyy-mm-dd')+(rownum-1) 日期 from user_objects where rownum<367 and to_date('2000-01-01','yyyy-mm-dd')+(rownum-1)<to_date('2001-01-01','yyyy-mm-dd')
    );
    --得到季度和月份对应关系
    select distinct to_char(日期,'q') 季度,to_char(to_date('2001-01-01','yyyy-mm-dd')+(rownum-1),'yyyymm') 日期 from(
    select to_date('2001-01','yyyy-mm')+(rownum-1) 日期 from user_objects where rownum<367 and to_date('2001-01-01','yyyy-mm-dd')+(rownum-1)<to_date('2002-01-01','yyyy-mm-dd')
    );
    --得到一年中的天数
    select to_char(to_date('2000-01-01','yyyy-mm-dd')+(rownum-1),'yyyy-mm-dd') 日期 from user_objects where rownum<367 and to_date('2000-01-01','yyyy-mm-dd')+(rownum-1)<to_date('2001-01-01','yyyy-mm-dd');
    ====================================================================================
    获取一个数据库的所有存储过程,可以用

    select * from sysobjects where type='p'

    ====================================================================================
    生成交*表的简单通用存储过程
    出处

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_qry]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[p_qry]
    GO

    /*--生成交*表的简单通用存储过程

    根据指定的表名,纵横字段,统计字段,自动生成交*表
    并可根据需要生成纵横两个方向的合计

    注意,横向 字段数目如果大于纵向字段数目,将自动交换纵横字段
    如果不要此功能,则去掉交换处理部分

    --邹建 204.06--*/

    /*--调用示例

    exec p_qry 'syscolumns','id','colid','colid',1,1
    --*/

    create proc p_qry
    @TableName sysname, --表名
    @纵轴 sysname, --交*表最左面的列
    @横轴 sysname, --交*表最上面的列
    @表体内容 sysname, --交*表的数数据字段
    @是否加横向合计 bit,--为1时在交*表横向最右边加横向合计
    @是否家纵向合计 bit --为1时在交*表纵向最下边加纵向合计
    as
    declare @s nvarchar(4000),@sql varchar(8000)

    --判断横向字段是否大于纵向字段数目,如果是,则交换纵横字段
    set @s='declare @a sysname
    if(select case when count(distinct ['+@纵轴+'])<count(distinct ['+@横轴+']) then 1 else 0 end
    from ['+@TableName+'])=1
    select @a=@纵轴,@纵轴=@横轴,@横轴=@a'
    exec sp_executesql @s
    ,N'@纵轴 sysname out,@横轴 sysname out'
    ,@纵轴 out,@横轴 out

    --生成交*表处理语句
    set @s='
    set @s=''''
    select @s=@s+'',[''+cast(['+@横轴+'] as varchar)+'']=sum(case ['+@横轴
    +'] when ''''''+cast(['+@横轴+'] as varchar)+'''''' then ['+@表体内容+'] else 0 end)''
    from ['+@TableName+']
    group by ['+@横轴+']'
    exec sp_executesql @s
    ,N'@s varchar(8000) out'
    ,@sql out

    --是否生成合计字段的处理
    declare @sum1 varchar(200),@sum2 varchar(200),@sum3 varchar(200)
    select @sum1=case @是否加横向合计
    when 1 then ',[合计]=sum(['+@表体内容+'])'
    else '' end
    ,@sum2=case @是否家纵向合计
    when 1 then '['+@纵轴+']=case grouping(['
    +@纵轴+']) when 1 then ''合计'' else cast(['
    +@纵轴+'] as varchar) end'
    else '['+@纵轴+']' end
    ,@sum3=case @是否家纵向合计
    when 1 then ' with rollup'
    else '' end

    --生成交*表
    exec('select '+@sum2+@sql+@sum1+'
    from ['+@TableName+']
    group by ['+@纵轴+']'+@sum3)
    go
    ==========================================================================================================
    利用排序规则特点计算汉字笔划和取得拼音首字母
    出处


      SQL SERVER的排序规则平时使用不是很多,也许不少初学者还比较陌生,但有
    一个错误大家应是经常碰到: SQL SERVER数据库,在跨库多表连接查询时,若两数据
    库默认字符集不同,系统就会返回这样的错误:

    “无法解决 equal to 操作的排序规则冲突。”

    一.错误分析:
      这个错误是因为排序规则不一致造成的,我们做个测试,比如:
    create table #t1(
    name varchar(20) collate Albanian_CI_AI_WS,
    value int)

    create table #t2(
    name varchar(20) collate Chinese_PRC_CI_AI_WS,
    value int )

    表建好后,执行连接查询:

    select * from #t1 A inner join #t2 B on A.name=B.name

    这样,错误就出现了:

    服务器: 消息 446,级别 16,状态 9,行 1
    无法解决 equal to 操作的排序规则冲突。
      要排除这个错误,最简单方法是,表连接时指定它的排序规则,这样错误就
    不再出现了。语句这样写:

    select *
    from #t1 A inner join #t2 B
    on A.name=B.name collate Chinese_PRC_CI_AI_WS

    二.排序规则简介:

    什么叫排序规则呢?MS是这样描述的:"在 Microsoft SQL Server 2000 中,
    字符串的物理存储由排序规则控制。排序规则指定表示每个字符的位模式以及存
    储和比较字符所使用的规则。"
      在查询分析器内执行下面语句,可以得到SQL SERVER支持的所有排序规则。

        select * from ::fn_helpcollations()

    排序规则名称由两部份构成,前半部份是指本排序规则所支持的字符集。
    如:
      Chinese_PRC_CS_AI_WS
    前半部份:指UNICODE字符集,Chinese_PRC_指针对大陆简体字UNICODE的排序规则。
    排序规则的后半部份即后缀 含义:
      _BIN 二进制排序
      _CI(CS) 是否区分大小写,CI不区分,CS区分
      _AI(AS) 是否区分重音,AI不区分,AS区分   
      _KI(KS) 是否区分假名类型,KI不区分,KS区分 
    _WI(WS) 是否区分宽度 WI不区分,WS区分 

    区分大小写:如果想让比较将大写字母和小写字母视为不等,请选择该选项。
    区分重音:如果想让比较将重音和非重音字母视为不等,请选择该选项。如果选择该选项,
    比较还将重音不同的字母视为不等。
    区分假名:如果想让比较将片假名和平假名日语音节视为不等,请选择该选项。
    区分宽度:如果想让比较将半角字符和全角字符视为不等,请选择该选项


    三.排序规则的应用:
      SQL SERVER提供了大量的WINDOWS和SQLSERVER专用的排序规则,但它的应用往往
    被开发人员所忽略。其实它在实践中大有用处。

      例1:让表NAME列的内容按拼音排序:

    create table #t(id int,name varchar(20))
    insert #t select 1,'中'
    union all select 2,'国'
    union all select 3,'人'
    union all select 4,'阿'

    select * from #t order by name collate Chinese_PRC_CS_AS_KS_WS
    drop table #t
    /*结果:
    id name
    ----------- --------------------
    4 阿
    2 国
    3 人
    1 中
    */

      例2:让表NAME列的内容按姓氏笔划排序:

    create table #t(id int,name varchar(20))

    insert #t select 1,'三'
    union all select 2,'乙'
    union all select 3,'二'
    union all select 4,'一'
    union all select 5,'十'
    select * from #t order by name collate Chinese_PRC_Stroke_CS_AS_KS_WS
    drop table #t
    /*结果:
    id name
    ----------- --------------------
    4 一
    2 乙
    3 二
    5 十
    1 三
    */

    四.在实践中排序规则应用的扩展
      SQL SERVER汉字排序规则可以按拼音、笔划等排序,那么我们如何利用这种功能
    来处理汉字的一些难题呢?我现在举个例子:

              用排序规则的特性计算汉字笔划

      要计算汉字笔划,我们得先做准备工作,我们知道,WINDOWS多国汉字,UNICODE目前
    收录汉字共20902个。简体GBK码汉字UNICODE值从19968开始。
      首先,我们先用SQLSERVER方法得到所有汉字,不用字典,我们简单利用SQL语句就
    可以得到:

    select top 20902 code=identity(int,19968,1) into #t from syscolumns a,syscolumns b

    再用以下语句,我们就得到所有汉字,它是按UNICODE值排序的:

      select code,nchar(code) as CNWord from #t

      然后,我们用SELECT语句,让它按笔划排序。

    select code,nchar(code) as CNWord
    from #t
    order by nchar(code) collate Chinese_PRC_Stroke_CS_AS_KS_WS,code

    结果:
    code CNWord
    ----------- ------
    19968 一
    20008 丨
    20022 丶
    20031 丿
    20032 乀
    20033 乁
    20057 乙
    20058 乚
    20059 乛
    20101 亅
    19969 丁
    ..........

      从上面的结果,我们可以清楚的看到,一笔的汉字,code是从19968到20101,从小到大排,但到
    了二笔汉字的第一个字“丁”,CODE为19969,就不按顺序而重新开始了。有了这结果,我们就可以轻
    松的用SQL语句得到每种笔划汉字归类的第一个或最后一个汉字。
    下面用语句得到最后一个汉字:

    create table #t1(id int identity,code int,cnword nvarchar(2))

    insert #t1(code,cnword)
    select code,nchar(code) as CNWord from #t
    order by nchar(code) collate Chinese_PRC_Stroke_CS_AS_KS_WS,code

    select A.cnword
    from #t1 A
    left join #t1 B on A.id=B.id-1 and A.code<B.code
    where B.code is null
    order by A.id

    得到36个汉字,每个汉字都是每种笔划数按Chinese_PRC_Stroke_CS_AS_KS_WS排序规则排序后的
    最后一个汉字:

    亅阝马风龙齐龟齿鸩龀龛龂龆龈龊龍龠龎龐龑龡龢龝齹龣龥齈龞麷鸞麣龖龗齾齉龘

      上面可以看出:“亅”是所有一笔汉字排序后的最后一个字,“阝”是所有二笔汉字排序后的最后
    一个字......等等。
      但同时也发现,从第33个汉字“龗(33笔)”后面的笔划有些乱,不正确。但没关系,比“龗”笔划
    多的只有四个汉字,我们手工加上:齾35笔,齉36笔,靐39笔,龘64笔

    建汉字笔划表(TAB_HZBH):
    create table tab_hzbh(id int identity,cnword nchar(1))
    --先插入前33个汉字
    insert tab_hzbh
    select top 33 A.cnword
    from #t1 A
    left join #t1 B on A.id=B.id-1 and A.code<B.code
    where B.code is null
    order by A.id
    --再加最后四个汉字
    set identity_insert tab_hzbh on
    go
    insert tab_hzbh(id,cnword)
         select 35,N'齾'
    union all select 36,N'齉'
    union all select 39,N'靐'
    union all select 64,N'龘'
    go
    set identity_insert tab_hzbh off
    go

      到此为止,我们可以得到结果了,比如我们想得到汉字“国”的笔划:

    declare @a nchar(1)
    set @a='国'select top 1 id
    from tab_hzbh
    where cnword>=@a collate Chinese_PRC_Stroke_CS_AS_KS_WS
    order by id
     

    id
    -----------
    8
    (结果:汉字“国”笔划数为8)

      上面所有准备过程,只是为了写下面这个函数,这个函数撇开上面建的所有临时表和固
    定表,为了通用和代码转移方便,把表tab_hzbh的内容写在语句内,然后计算用户输入一串
    汉字的总笔划:

    create function fun_getbh(@str nvarchar(4000))
    returns int
    as
    begin
    declare @word nchar(1),@n int
    set @n=0
    while len(@str)>0
    begin
    set @word=left(@str,1)
    --如果非汉字,笔划当0计
    set @n=@n+(case when unicode(@word) between 19968 and 19968+20901
    then (select top 1 id from (
    select 1 as id,N'亅' as word
    union all select 2,N'阝'
    union all select 3,N'马'
    union all select 4,N'风'
    union all select 5,N'龙'
    union all select 6,N'齐'
    union all select 7,N'龟'
    union all select 8,N'齿'
    union all select 9,N'鸩'
    union all select 10,N'龀'
    union all select 11,N'龛'
    union all select 12,N'龂'
    union all select 13,N'龆'
    union all select 14,N'龈'
    union all select 15,N'龊'
    union all select 16,N'龍'
    union all select 17,N'龠'
    union all select 18,N'龎'
    union all select 19,N'龐'
    union all select 20,N'龑'
    union all select 21,N'龡'
    union all select 22,N'龢'
    union all select 23,N'龝'
    union all select 24,N'齹'
    union all select 25,N'龣'
    union all select 26,N'龥'
    union all select 27,N'齈'
    union all select 28,N'龞'
    union all select 29,N'麷'
    union all select 30,N'鸞'
    union all select 31,N'麣'
    union all select 32,N'龖'
    union all select 33,N'龗'
    union all select 35,N'齾'
    union all select 36,N'齉'
    union all select 39,N'靐'
    union all select 64,N'龘'
    ) T
    where word>=@word collate Chinese_PRC_Stroke_CS_AS_KS_WS
    order by id ASC) else 0 end)
    set @str=right(@str,len(@str)-1)
    end
    return @n
    end

    --函数调用实例:
    select dbo.fun_getbh('中华人民共和国'),dbo.fun_getbh('中華人民共和國')
     
      执行结果:笔划总数分别为39和46,简繁体都行。

    当然,你也可以把上面“UNION ALL”内的汉字和笔划改存在固定表内,在汉字
    列建CLUSTERED INDEX,列排序规则设定为:
        Chinese_PRC_Stroke_CS_AS_KS_WS
    这样速度更快。如果你用的是BIG5码的操作系统,你得另外生成汉字,方法一样。
    但有一点要记住:这些汉字是通过SQL语句SELECT出来的,不是手工输入的,更不
    是查字典得来的,因为新华字典毕竟不同于UNICODE字符集,查字典的结果会不正
    确。

      
        用排序规则的特性得到汉字拼音首字母

      用得到笔划总数相同的方法,我们也可以写出求汉字拼音首字母的函数。如下:

    create function fun_getPY(@str nvarchar(4000))
    returns nvarchar(4000)
    as
    begin
    declare @word nchar(1),@PY nvarchar(4000)
    set @PY=''
    while len(@str)>0
    begin
    set @word=left(@str,1)
    --如果非汉字字符,返回原字符
    set @PY=@PY+(case when unicode(@word) between 19968 and 19968+20901
    then (select top 1 PY from (
    select 'A' as PY,N'驁' as word
    union all select 'B',N'簿'
    union all select 'C',N'錯'
    union all select 'D',N'鵽'
    union all select 'E',N'樲'
    union all select 'F',N'鰒'
    union all select 'G',N'腂'
    union all select 'H',N'夻'
    union all select 'J',N'攈'
    union all select 'K',N'穒'
    union all select 'L',N'鱳'
    union all select 'M',N'旀'
    union all select 'N',N'桛'
    union all select 'O',N'漚'
    union all select 'P',N'曝'
    union all select 'Q',N'囕'
    union all select 'R',N'鶸'
    union all select 'S',N'蜶'
    union all select 'T',N'籜'
    union all select 'W',N'鶩'
    union all select 'X',N'鑂'
    union all select 'Y',N'韻'
    union all select 'Z',N'咗'
    ) T
    where word>=@word collate Chinese_PRC_CS_AS_KS_WS
    order by PY ASC) else @word end)
    set @str=right(@str,len(@str)-1)
    end
    return @PY
    end

    --函数调用实例:
    select dbo.fun_getPY('中华人民共和国'),dbo.fun_getPY('中華人民共和國')
    结果都为:ZHRMGHG

      你若有兴趣,也可用相同的方法,扩展为得到汉字全拼的函数,甚至还可以得到全拼的读
    音声调,不过全拼分类大多了。得到全拼最好是用对照表,两万多汉字搜索速度很快,用对照
    表还可以充分利用表的索引。
    排序规则还有很多其它的巧妙用法,限于篇幅在此就不再详细说明。欢迎大家共同探讨。
    ==================================================================================================
    如何实现对数据库单个字段进行加密 选择自 callzjy 的 Blog
    关键字 callzjy 字段加密 sqlserver 函数
    出处

    create view v_rand

    as

    select c=unicode(cast(round(rand()*255,0) as tinyint))

    go

    create function f_jmstr(@str varchar(8000),@type bit)returns varchar(8000)

    /*

    *参数说明

    *str:要加密的字符串或已经加密后的字符

    *type:操作类型--0加密--解密

    *返回值说明

    *当操作类型为加密时(type--0):返回为加密后的str,即存放于数据库中的字符串

    *当操作类型为解密时(type--1):返回为实际字符串,即加密字符串解密后的原来字符串

    */

    As

    begin

    declare @re varchar(8000)--返回值

    declare @c int--加密字符

    declare @i int

    /*

    *加密方法为原字符异或一个随机ASCII字符

    */
    if @type=0--加密
    begin
    select @c=c,@re='',@i=len(@str) from v_rand
    while @i>0
    select @re=nchar(unicode(substring(@str,@i,1))^@c^@i)+@re
    ,@i=@i-1
    set @re=@re+nchar(@c)
    end
    else--解密
    begin
    select @i=len(@str)-1,@c=unicode(substring(@str,@i+1,1)),@re=''
    while @i>0
    select @re=nchar(unicode(substring(@str,@i,1))^@c^@i)+@re ,@i=@i-1
    end
    return(@re)
    end
    go
    --测试
    declare @tempstr varchar(20)
    set @tempstr=' 1 2 3aA'
    select dbo.f_jmstr(dbo.f_jmstr(@tempstr,0),1)
    输出结果
    1 2 3aA
    (完)
    ==================================================================================================
    让数据库产生一张详细的日历表

    也许有了这张表,你的工作会轻松很多!

    CREATE TABLE [dbo].[time_dimension] (
    [time_id] [int] IDENTITY (1, 1) NOT NULL ,
    [the_date] [datetime] NULL ,
    [the_day] [nvarchar] (15) NULL ,
    [the_month] [nvarchar] (15) NULL ,
    [the_year] [smallint] NULL ,
    [day_of_month] [smallint] NULL ,
    [week_of_year] [smallint] NULL ,
    [month_of_year] [smallint] NULL ,
    [quarter] [nvarchar] (2) NULL ,
    [fiscal_period] [nvarchar] (20) NULL
    ) ON [PRIMARY]


    DECLARE @WeekString varchar(12),
    @dDate SMALLDATETIME,
    @sMonth varchar(20),
    @iYear smallint,
    @iDayOfMonth smallint,
    @iWeekOfYear smallint,
    @iMonthOfYear smallint,
    @sQuarter varchar(2),
    @sSQL varchar(100),
    @adddays int

    SELECT @adddays = 1 --日期增量(可以自由设定)
    SELECT @dDate = '01/01/2002' --开始日期

    WHILE @dDate < '12/31/2004' --结束日期
    BEGIN

    SELECT @WeekString = DATENAME (dw, @dDate)
    SELECT @sMonth=DATENAME(mm,@dDate)
    SELECT @iYear= DATENAME (yy, @dDate)
    SELECT @iDayOfMonth=DATENAME (dd, @dDate)
    SELECT @iWeekOfYear= DATENAME (week, @dDate)
    SELECT @iMonthOfYear=DATEPART(month, @dDate)
    SELECT @sQuarter = 'Q' + CAST(DATENAME (quarter, @dDate)as varchar(1))

    INSERT INTO time_dimension(the_date, the_day, the_month, the_year,
    day_of_month,
    week_of_year, month_of_year, quarter) VALUES
    (@dDate, @WeekString, @sMonth, @iYear, @iDayOfMonth, @iWeekOfYear,
    @iMonthOfYear, @sQuarter)
    SELECT @dDate = @dDate + @adddays
    END
    GO

    select * from time_dimension

    =================================================================================
    --搜索某个字符串在那个表的那个字段中
    declare @str varchar(100)
    set @str='White' --要搜索的字符串
    declare @s varchar(8000)
    declare tb cursor local for
    select s='if exists(select 1 from ['+b.name+'] where ['+a.name+'] like ''%'+@str+'%'')
    print ''所在的表及 字段: ['+b.name+'].['+a.name+']'''
    from syscolumns a join sysobjects b on a.id=b.id
    where b.xtype='U' and a.status>=0
    and a.xusertype in(175,239,231,167)
    open tb
    fetch next from tb into @s
    while @@fetch_status=0
    begin
    exec(@s)
    fetch next from tb into @s
    end
    close tb
    deallocate tb
    /*--测试结果
    所在的表及字段: [authors].[au_lname]
    --*/
    ======================================================================================
    --查询指定的表在那些数据库中存在

    declare @tbname sysname
    set @tbname='客户资料'

    declare @dbname sysname,@sql nvarchar(4000),@re bit,@sql1 varchar(8000)
    set @sql1=''
    declare tb cursor for select name from master..sysdatabases
    open tb
    fetch next from tb into @dbname
    while @@fetch_status=0
    begin
    set @sql='set @re=case when exists(select 1 from ['
    +@dbname+']..sysobjects where xtype=''U'' and name='''
    +@tbname+''') then 1 else 0 end'
    exec sp_executesql @sql,N'@re bit out',@re out
    if @re=1 set @sql1=@sql1+' union all select '''+@dbname+''''
    fetch next from tb into @dbname
    end
    close tb
    deallocate tb
    set @sql1=substring(@sql1,12,8000)
    exec(@sql1)

    ======================================================================================
    比较两个数据库的表结构差异 选择自 zjcxc 的 Blog
    关键字 表结构,差异
    出处

    /*--比较两个数据库的表结构差异

    --*/
    /*--调用示例

    exec p_comparestructure 'xzkh_model','xzkh_new'
    --*/

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_comparestructure]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[p_comparestructure]
    GO

    create proc p_comparestructure
    @dbname1 varchar(250), --要比较的数据库名1
    @dbname2 varchar(250) --要比较的数据库名2
    as
    create table #tb1(表名1 varchar(250),字段名 varchar(250),序号 int,标识 bit,主键 bit,类型 varchar(250),
    占用字节数 int,长度 int,小数位数 int,允许空 bit,默认值 varchar(500),字段说明 varchar(500))

    create table #tb2(表名2 varchar(250),字段名 varchar(250),序号 int,标识 bit,主键 bit,类型 varchar(250),
    占用字节数 int,长度 int,小数位数 int,允许空 bit,默认值 varchar(500),字段说明 varchar(500))

    --得到数据库1的结构
    exec('insert into #tb1 SELECT
    表名=d.name,字段名=a.name,序号=a.colid,
    标识=case when a.status=0x80 then 1 else 0 end,
    主键=case when exists(SELECT 1 FROM '+@dbname1+'..sysobjects where xtype=''PK'' and name in (
    SELECT name FROM '+@dbname1+'..sysindexes WHERE indid in(
    SELECT indid FROM '+@dbname1+'..sysindexkeys WHERE id = a.id AND colid=a.colid
    ))) then 1 else 0 end,
    类型=b.name, 占用字节数=a.length,长度=a.prec,小数位数=a.scale, 允许空=a.isnullable,
    默认值=isnull(e.text,''''''),字段说明=isnull(g.[value],'''''')
    FROM '+@dbname1+'..syscolumns a
    left join '+@dbname1+'..systypes b on a.xtype=b.xusertype
    inner join '+@dbname1+'..sysobjects d on a.id=d.id and d.xtype=''U'' and d.name<>''dtproperties''
    left join '+@dbname1+'..syscomments e on a.cdefault=e.id
    left join '+@dbname1+'..sysproperties g on a.id=g.id and a.colid=g.smallid
    order by a.id,a.colorder')

    --得到数据库2的结构
    exec('insert into #tb2 SELECT
    表名=d.name,字段名=a.name,序号=a.colid,
    标识=case when a.status=0x80 then 1 else 0 end,
    主键=case when exists(SELECT 1 FROM '+@dbname2+'..sysobjects where xtype=''PK'' and name in (
    SELECT name FROM '+@dbname2+'..sysindexes WHERE indid in(
    SELECT indid FROM '+@dbname2+'..sysindexkeys WHERE id = a.id AND colid=a.colid
    ))) then 1 else 0 end,
    类型=b.name, 占用字节数=a.length,长度=a.prec,小数位数=a.scale, 允许空=a.isnullable,
    默认值=isnull(e.text,''''''),字段说明=isnull(g.[value],'''''')
    FROM '+@dbname2+'..syscolumns a
    left join '+@dbname2+'..systypes b on a.xtype=b.xusertype
    inner join '+@dbname2+'..sysobjects d on a.id=d.id and d.xtype=''U'' and d.name<>''dtproperties''
    left join '+@dbname2+'..syscomments e on a.cdefault=e.id
    left join '+@dbname2+'..sysproperties g on a.id=g.id and a.colid=g.smallid
    order by a.id,a.colorder')
    --and not exists(select 1 from #tb2 where 表名2=a.表名1)
    select 比较结果=case when a.表名1 is null and b.序号=1 then '库1缺少表:'+b.表名2
    when b.表名2 is null and a.序号=1 then '库2缺少表:'+a.表名1
    when a.字段名 is null and exists(select 1 from #tb1 where 表名1=b.表名2) then '库1 ['+b.表名2+'] 缺少字段:'+b.字段名
    when b.字段名 is null and exists(select 1 from #tb2 where 表名2=a.表名1) then '库2 ['+a.表名1+'] 缺少字段:'+a.字段名
    when a.标识<>b.标识 then '标识不同'
    when a.主键<>b.主键 then '主键设置不同'
    when a.类型<>b.类型 then '字段类型不同'
    when a.占用字节数<>b.占用字节数 then '占用字节数'
    when a.长度<>b.长度 then '长度不同'
    when a.小数位数<>b.小数位数 then '小数位数不同'
    when a.允许空<>b.允许空 then '是否允许空不同'
    when a.默认值<>b.默认值 then '默认值不同'
    when a.字段说明<>b.字段说明 then '字段说明不同'
    else '' end,
    *
    from #tb1 a
    full join #tb2 b on a.表名1=b.表名2 and a.字段名=b.字段名
    where a.表名1 is null or a.字段名 is null or b.表名2 is null or b.字段名 is null
    or a.标识<>b.标识 or a.主键<>b.主键 or a.类型<>b.类型
    or a.占用字节数<>b.占用字节数 or a.长度<>b.长度 or a.小数位数<>b.小数位数
    or a.允许空<>b.允许空 or a.默认值<>b.默认值 or a.字段说明<>b.字段说明
    order by isnull(a.表名1,b.表名2),isnull(a.序号,b.序号)--isnull(a.字段名,b.字段名)
    go
    ==========================================================================================
    行列转换 交*表
    出处

    总结了一些有代表性的贴子,具体见http://expert.csdn.net/Expert/topic/2440/2440306.xml?temp=.6941645

    1: 列转为行:
    eg1:
    Create table test (name char(10),km char(10),cj int)
    go
    insert test values('张三','语文',80)
    insert test values('张三','数学',86)
    insert test values('张三','英语',75)
    insert test values('李四','语文',78)
    insert test values('李四','数学',85)
    insert test values('李四','英语',78)

    想变成

    姓名 语文 数学 英语
    张三 80 86 75
    李四 78 85 78

    declare @sql varchar(8000)
    set @sql = 'select name'
    select @sql = @sql + ',sum(case km when '''+km+''' then cj end) ['+km+']'
    from (select distinct km from test) as a
    select @sql = @sql+' from test group by name'
    exec (@sql)

    drop table test

    eg2:
    有表A,
    id pid
    1 1
    1 2
    1 3
    2 1
    2 2
    3 1
    如何化成表B:
    id pid
    1 1,2,3
    2 1,2
    3 1
    或者是从表B变成A(不要用游标)
    以前有相似的列子,现在找不到了,帮帮忙!

    --1.创建一个合并的函数
    create function fmerg(@id int)
    returns varchar(8000)
    as
    begin
    declare @str varchar(8000)
    set @str=''
    select @str=@str+','+cast(pid as varchar) from 表A where id=@id
    set @str=right(@str,len(@str)-1)
    return(@str)
    End
    go

    --调用自定义函数得到结果
    select distinct id,dbo.fmerg(id) from 表A

    2:
    /*********** 行转列 *****************/
    测试:
    create table t1 (a int,b int,c int,d int,e int,f int,g int,h int)
    insert t1 values(15, 9, 1, 0, 1, 2, 2, 0)

    declare @ varchar(8000)
    set @=''
    select @=@+rtrim(name)+' from t1 union all select ' from syscolumns where id=object_id('t1')
    set @=left(@,len(@)-len(' from t1 union all select '))
    --print @
    exec('select '+@+' from t1')

    a
    -----------
    15
    9
    1
    0
    1
    2
    2
    0
    ====================================================================================================
    动态SQL语句 选择自 txlicenhe 的 Blog
    关键字 动态SQL EXEC SP_EXECUTESQL
    出处

    1:
    普通SQL语句可以用Exec执行
    eg: Select * from tableName
    Exec('select * from tableName')
    sp_executesql N'select * from tableName' -- 请注意字符串前一定要加N

    2:
    字段名,表名,数据库名之类作为变量时,必须用动态SQL
    eg:
    declare @fname varchar(20)
    set @fname = '[name]'
    Select @fname from sysobjects -- 错误
    Exec('select ' + @fname + ' from sysobjects') -- 请注意 加号前后的 单引号的边上要加空格
    exec sp_executesql N' select ' + @fname + ' from sysobjects'
    当然将字符串改成变量的形式也可
    declare @s varchar(1000)
    set @s = 'select ' + @fname + ' from sysobjects'
    Exec(@s) -- 成功
    exec sp_executesql @s -- 此句会报错

    declare @s Nvarchar(1000) -- 注意此处改为nvarchar(1000)
    set @s = 'select ' + @fname + ' from sysobjects'
    Exec(@s) -- 成功
    exec sp_executesql @s -- 此句正确,

    3: 输出参数
    eg:
    declare @num,
    @sqls
    set @sqls='select count(*) from ' + @servername + '.a.dbo.b'
    exec(@sqls)
    我如何能将exec执行的结果存入变量@num中

    declare @num int,
    @sqls nvarchar(4000)
    set @sqls='select @a=count(*) from '+@servername+'.a.dbo.b'
    exec sp_executesql @sqls,N'@a int output',@num output
    select @num
    =========================================================================================

    介紹取一表前N筆記錄的各种數据庫的寫法...

    作者﹕CCBZZP

    1. ORACLE
    SELECT * FROM TABLE1 WHERE ROWNUM<=N
    2. INFORMIX
    SELECT FIRST N * FROM TABLE1
    3. DB2
    SELECT * ROW_NUMBER() OVER(ORDER BY COL1 DESC) AS ROWNUM WHERE ROWNUM<=N
    或者
    SELECT COLUMN FROM TABLE FETCH FIRST N ROWS ONLY
    4. SQL SERVER
    SELECT TOP N * FROM TABLE1
    5. SYBASE
    SET ROWCOUNT N
    GO
    SELECT * FROM TABLE1
    6. MYSQL
    SELECT * FROM TABLE1 LIMIT N
    7. FOXPRO
    SELECT * TOP N FROM TABLE ORDER BY COLUMN
    ===================================================================================

    create procedure SP_GET_TABLE_INFO
    @ObjName varchar(128) /* The table to generate sql script */
    as

    declare @Script varchar(255)
    declare @ColName varchar(30)
    declare @ColID TinyInt
    declare @UserType smallint
    declare @TypeName sysname
    declare @Length TinyInt
    declare @Prec TinyInt
    declare @Scale TinyInt
    declare @Status TinyInt
    declare @cDefault int
    declare @DefaultID TinyInt
    declare @Const_Key varchar(255)
    declare @IndID SmallInt
    declare @IndStatus Int
    declare @Index_Key varchar(255)
    declare @DBName varchar(30)
    declare @strPri_Key varchar (255)

    /*
    ** Check to see the the table exists and initialize @objid.
    */
    if not Exists(Select name from sysobjects where name = @ObjName)
    begin
    select @DBName = db_name()
    raiserror(15009,-1,-1,@ObjName,@DBName)
    return (1)
    end

    create table #spscript
    (
    id int IDENTITY not null,
    Script Varchar(255) NOT NULL,
    LastLine tinyint
    )

    declare Cursor_Column INSENSITIVE CURSOR
    for Select a.name,a.ColID,a.usertype,b.name,a.length,a.prec,a.scale,a.Status, a.cDefault,
    case a.cdefault when 0 then ' ' else (select c.Text from syscomments c where a.cdefault = c.id) end const_key
    from syscolumns a, systypes b where object_name(a.id) = @ObjName
    and a.usertype = b.usertype order by a.ColID

    set nocount on
    Select @Script = 'Create table ' + @ObjName + '('
    Insert into #spscript values(@Script,0)

    /* Get column information */
    open Cursor_Column

    fetch next from Cursor_Column into @ColName,@ColID,@UserType,@TypeName,@Length,@Prec,@Scale,
    @Status,@cDefault,@Const_Key

    Select @Script = ''
    while (@@FETCH_STATUS <> -1)
    begin
    if (@@FETCH_STATUS <> -2)
    begin
    Select @Script = @ColName + ' ' + @TypeName
    if @UserType in (1,2,3,4)
    Select @Script = @Script + '(' + Convert(char(3),@Length) + ') '
    else if @UserType in (24)
    Select @Script = @Script + '(' + Convert(char(3),@Prec) + ','
    + Convert(char(3),@Scale) + ') '
    else
    Select @Script = @Script + ' '
    if ( @Status & 0x80 ) > 0
    Select @Script = @Script + ' IDENTITY(1,1) '

    if ( @Status & 0x08 ) > 0
    Select @Script = @Script + ' NULL '
    else
    Select @Script = @Script + ' NOT NULL '
    if @cDefault > 0
    Select @Script = @Script + ' DEFAULT ' + @Const_Key
    end
    fetch next from Cursor_Column into @ColName,@ColID,@UserType,@TypeName,@Length,@Prec,@Scale,
    @Status,@cDefault,@Const_Key
    if @@FETCH_STATUS = 0
    begin
    Select @Script = @Script + ','
    Insert into #spscript values(@Script,0)
    end
    else
    begin
    Insert into #spscript values(@Script,1)
    Insert into #spscript values(')',0)
    end
    end
    Close Cursor_Column
    Deallocate Cursor_Column

    /* Get index information */
    Declare Cursor_Index INSENSITIVE CURSOR
    for Select name,IndID,status from sysindexes where object_name(id)=@ObjName
    and IndID > 0 and IndID<>255 order by IndID /*增加了对InDid为255的判断*/
    Open Cursor_Index
    Fetch Next from Cursor_Index into @ColName, @IndID, @IndStatus
    while (@@FETCH_STATUS <> -1)
    begin
    if @@FETCH_STATUS <> -2
    begin

    declare @i TinyInt
    declare @thiskey varchar(50)
    declare @IndDesc varchar(68) /* string to build up index desc in */

    Select @i = 1
    while (@i <= 16)
    begin
    select @thiskey = index_col(@ObjName, @IndID, @i)
    if @thiskey is null
    break

    if @i = 1
    select @Index_Key = index_col(@ObjName, @IndID, @i)
    else
    select @Index_Key = @Index_Key + ', ' + index_col(@ObjName, @IndID, @i)
    select @i = @i + 1
    end
    if (@IndStatus & 0x02) > 0
    Select @Script = 'Create unique '
    else
    Select @Script = 'Create '
    if @IndID = 1
    select @Script = @Script + ' clustered '

    if (@IndStatus & 0x800) > 0
    select @strPri_Key = ' PRIMARY KEY (' + @Index_Key + ')'
    else
    select @strPri_Key = ''

    if @IndID > 1
    select @Script = @Script + ' nonclustered '
    Select @Script = @Script + ' index ' + @ColName + ' ON '+ @ObjName
    + '(' + @Index_Key + ')'
    Select @IndDesc = ''
    /*
    ** See if the index is ignore_dupkey (0x01).
    */
    if @IndStatus & 0x01 = 0x01
    Select @IndDesc = @IndDesc + ' IGNORE_DUP_KEY' + ','
    /*
    ** See if the index is ignore_dup_row (0x04).
    */
    /* if @IndStatus & 0x04 = 0x04 */
    /* Select @IndDesc = @IndDesc + ' IGNORE_DUP_ROW' + ',' */ /* 2000 不在支持*/
    /*
    ** See if the index is allow_dup_row (0x40).
    */
    if @IndStatus & 0x40 = 0x40
    Select @IndDesc = @IndDesc + ' ALLOW_DUP_ROW' + ','
    if @IndDesc <> ''
    begin
    Select @IndDesc = SubString( @IndDesc, 1, DataLength(@IndDesc) - 1 )
    Select @Script = @Script + ' WITH ' + @IndDesc
    end
    /*
    ** Add the location of the data.
    */
    end
    if (@strPri_Key = '')
    Insert into #spscript values(@Script,0)
    else
    update #spscript set Script = Script + @strPri_Key where LastLine = 1

    Fetch Next from Cursor_Index into @ColName, @IndID, @IndStatus
    end
    Close Cursor_Index
    Deallocate Cursor_Index

    Select Script from #spscript

    set nocount off

    return (0)

    ==============================================================================================
    收藏几段SQL Server语句和存储过程

    -- ======================================================

    --列出SQL SERVER 所有表,字段名,主键,类型,长度,小数位数等信息

    --在查询分析器里运行即可,可以生成一个表,导出到EXCEL中

    -- ======================================================

    SELECT

    (case when a.colorder=1 then d.name else '' end)表名,

    a.colorder 字段序号,

    a.name 字段名,

    (case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then '√'else '' end) 标识,

    (case when (SELECT count(*)

    FROM sysobjects

    WHERE (name in

    (SELECT name

    FROM sysindexes

    WHERE (id = a.id) AND (indid in

    (SELECT indid

    FROM sysindexkeys

    WHERE (id = a.id) AND (colid in

    (SELECT colid

    FROM syscolumns

    WHERE (id = a.id) AND (name = a.name))))))) AND

    (xtype = 'PK'))>0 then '√' else '' end) 主键,

    b.name 类型,

    a.length 占用字节数,

    COLUMNPROPERTY(a.id,a.name,'PRECISION') as 长度,

    isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0) as 小数位数,

    (case when a.isnullable=1 then '√'else '' end) 允许空,

    isnull(e.text,'') 默认值,

    isnull(g.[value],'') AS 字段说明

    FROM syscolumns a left join systypes b

    on a.xtype=b.xusertype

    inner join sysobjects d

    on a.id=d.id and d.xtype='U' and d.name<>'dtproperties'

    left join syscomments e

    on a.cdefault=e.id

    left join sysproperties g

    on a.id=g.id AND a.colid = g.smallid

    order by a.id,a.colorder

    -------------------------------------------------------------------------------------------------

    列出SQL SERVER 所有表、字段定义,类型,长度,一个值等信息

    并导出到Excel 中

    -- -- Export all user tables definition and one sample value

    -- jan-13-2003,Dr.Zhang

    -- 在查询分析器里运行:

    SET ANSI_NULLS OFF

    GO

    SET NOCOUNT ON

    GO

    SET LANGUAGE 'Simplified Chinese'

    go

    DECLARE @tbl nvarchar(200),@fld nvarchar(200),@sql nvarchar(4000),@maxlen int,@sample nvarchar(40)

    SELECT d.name TableName,a.name FieldName,b.name TypeName,a.length Length,a.isnullable IS_NULL INTO #t

    FROM syscolumns a, systypes b,sysobjects d

    WHERE a.xtype=b.xusertype and a.id=d.id and d.xtype='U'

    DECLARE read_cursor CURSOR

    FOR SELECT TableName,FieldName FROM #t

    SELECT TOP 1 '_TableName ' TableName,

    'FieldName ' FieldName,'TypeName ' TypeName,

    'Length' Length,'IS_NULL' IS_NULL,

    'MaxLenUsed' AS MaxLenUsed,'Sample Value ' Sample,

    'Comment ' Comment INTO #tc FROM #t

    OPEN read_cursor

    FETCH NEXT FROM read_cursor INTO @tbl,@fld

    WHILE (@@fetch_status <> -1) --- failes

    BEGIN

    IF (@@fetch_status <> -2) -- Missing

    BEGIN

    SET @sql=N'SET @maxlen=(SELECT max(len(cast('+@fld+' as nvarchar))) FROM '+@tbl+')'

    --PRINT @sql

    EXEC SP_EXECUTESQL @sql,N'@maxlen int OUTPUT',@maxlen OUTPUT

    --print @maxlen

    SET @sql=N'SET @sample=(SELECT TOP 1 cast('+@fld+' as nvarchar) FROM '+@tbl+' WHERE len(cast('+@fld+' as nvarchar))='+convert(nvarchar(5),@maxlen)+')'

    EXEC SP_EXECUTESQL @sql,N'@sample varchar(30) OUTPUT',@sample OUTPUT

    --for quickly

    --SET @sql=N'SET @sample=convert(varchar(20),(SELECT TOP 1 '+@fld+' FROM '+

    --@tbl+' order by 1 desc ))'

    PRINT @sql

    print @sample

    print @tbl

    EXEC SP_EXECUTESQL @sql,N'@sample nvarchar(30) OUTPUT',@sample OUTPUT

    INSERT INTO #tc SELECT *,ltrim(ISNULL(@maxlen,0)) as MaxLenUsed,

    convert(nchar(20),ltrim(ISNULL(@sample,' '))) as Sample,' ' Comment FROM #t where TableName=@tbl and FieldName=@fld

    END

    FETCH NEXT FROM read_cursor INTO @tbl,@fld

    END

    CLOSE read_cursor

    DEALLOCATE read_cursor

    GO

    SET ANSI_NULLS ON

    GO

    SET NOCOUNT OFF

    GO

    select count(*) from #t

    DROP TABLE #t

    GO

    select count(*)-1 from #tc

    select * into ##tx from #tc order by tablename

    DROP TABLE #tc

    --select * from ##tx

    declare @db nvarchar(60),@sql nvarchar(3000)

    set @db=db_name()

    --请修改用户名和口令 导出到Excel 中

    set @sql='exec master.dbo.xp_cmdshell ''bcp ..dbo.##tx out c:\'+@db+'_exp.xls -w -C936 -Usa -Psa '''

    print @sql

    exec(@sql)

    GO

    DROP TABLE ##tx

    GO

    -- 根据表中数据生成insert语句的存储过程

    --建立存储过程,执行 spGenInsertSQL 表名

    --感谢playyuer

    -- CREATE proc spGenInsertSQL (@tablename varchar(256))

    as

    begin

    declare @sql varchar(8000)

    declare @sqlValues varchar(8000)

    set @sql =' ('

    set @sqlValues = 'values (''+'

    select @sqlValues = @sqlValues + cols + ' + '','' + ' ,@sql = @sql + '[' + name + '],'

    from

    (select case

    when xtype in (48,52,56,59,60,62,104,106,108,122,127)

    then 'case when '+ name +' is null then ''NULL'' else ' + 'cast('+ name + ' as varchar)'+' end'

    when xtype in (58,61)

    then 'case when '+ name +' is null then ''NULL'' else '+''''''''' + ' + 'cast('+ name +' as varchar)'+ '+'''''''''+' end'

    when xtype in (167)

    then 'case when '+ name +' is null then ''NULL'' else '+''''''''' + ' + 'replace('+ name+','''''''','''''''''''')' + '+'''''''''+' end'

    when xtype in (231)

    then 'case when '+ name +' is null then ''NULL'' else '+'''N'''''' + ' + 'replace('+ name+','''''''','''''''''''')' + '+'''''''''+' end'

    when xtype in (175)

    then 'case when '+ name +' is null then ''NULL'' else '+''''''''' + ' + 'cast(replace('+ name+','''''''','''''''''''') as Char(' + cast(length as varchar) + '))+'''''''''+' end'

    when xtype in (239)

    then 'case when '+ name +' is null then ''NULL'' else '+'''N'''''' + ' + 'cast(replace('+ name+','''''''','''''''''''') as Char(' + cast(length as varchar) + '))+'''''''''+' end'

    else '''NULL'''

    end as Cols,name

    from syscolumns

    where id = object_id(@tablename)

    ) T

    set @sql ='select ''INSERT INTO ['+ @tablename + ']' + left(@sql,len(@sql)-1)+') ' + left(@sqlValues,len(@sqlValues)-4) + ')'' from '+@tablename

    --print @sql

    exec (@sql)

    end

    GO

    -- --根据表中数据生成insert语句的存储过程

    --建立存储过程,执行 proc_insert 表名

    --感谢Sky_blue

    --

    CREATE proc proc_insert (@tablename varchar(256))

    as

    begin

    set nocount on

    declare @sqlstr varchar(4000)

    declare @sqlstr1 varchar(4000)

    declare @sqlstr2 varchar(4000)

    select @sqlstr='select ''insert '+@tablename

    select @sqlstr1=''

    select @sqlstr2=' ('

    select @sqlstr1= ' values ( ''+'

    select @sqlstr1=@sqlstr1+col+'+'',''+' ,@sqlstr2=@sqlstr2+name +',' from (select case

    -- when a.xtype =173 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar('+convert(varchar(4),a.length*2+2)+'),'+a.name +')'+' end'

    when a.xtype =104 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(1),'+a.name +')'+' end'

    when a.xtype =175 then 'case when '+a.name+' is null then ''NULL'' else '+'''''''''+'+'replace('+a.name+','''''''','''''''''''')' + '+'''''''''+' end'

    when a.xtype =61 then 'case when '+a.name+' is null then ''NULL'' else '+'''''''''+'+'convert(varchar(23),'+a.name +',121)'+ '+'''''''''+' end'

    when a.xtype =106 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar('+convert(varchar(4),a.xprec+2)+'),'+a.name +')'+' end'

    when a.xtype =62 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(23),'+a.name +',2)'+' end'

    when a.xtype =56 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(11),'+a.name +')'+' end'

    when a.xtype =60 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(22),'+a.name +')'+' end'

    when a.xtype =239 then 'case when '+a.name+' is null then ''NULL'' else '+'''''''''+'+'replace('+a.name+','''''''','''''''''''')' + '+'''''''''+' end'

    when a.xtype =108 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar('+convert(varchar(4),a.xprec+2)+'),'+a.name +')'+' end'

    when a.xtype =231 then 'case when '+a.name+' is null then ''NULL'' else '+'''''''''+'+'replace('+a.name+','''''''','''''''''''')' + '+'''''''''+' end'

    when a.xtype =59 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(23),'+a.name +',2)'+' end'

    when a.xtype =58 then 'case when '+a.name+' is null then ''NULL'' else '+'''''''''+'+'convert(varchar(23),'+a.name +',121)'+ '+'''''''''+' end'

    when a.xtype =52 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(12),'+a.name +')'+' end'

    when a.xtype =122 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(22),'+a.name +')'+' end'

    when a.xtype =48 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(6),'+a.name +')'+' end'

    -- when a.xtype =165 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar('+convert(varchar(4),a.length*2+2)+'),'+a.name +')'+' end'

    when a.xtype =167 then 'case when '+a.name+' is null then ''NULL'' else '+'''''''''+'+'replace('+a.name+','''''''','''''''''''')' + '+'''''''''+' end'

    else '''NULL'''

    end as col,a.colid,a.name

    from syscolumns a where a.id = object_id(@tablename) and a.xtype <>189 and a.xtype <>34 and a.xtype <>35 and a.xtype <>36

    )t order by colid

    select @sqlstr=@sqlstr+left(@sqlstr2,len(@sqlstr2)-1)+') '+left(@sqlstr1,len(@sqlstr1)-3)+')'' from '+@tablename

    -- print @sqlstr

    exec( @sqlstr)

    set nocount off

    end

    GO

    说明:本贴纯属收藏,目的在于大家交流,在此对作者表示感谢!

    ==========================================================================================
    小写转大写金额 选择自 webmin 的 Blog
    关键字 金额 SQL Server
    出处

    在网上见到一个Oracle的版本的小写转大写金额的函数,感觉还不错现在把它转成SQL Server版本。

    /********************************************************
    作者:(birdie_7761@cmmail.com)
    版本:1.0
    创建时间:20020227
    修改时间:
    功能:小写金额转换成大写
    参数:n_LowerMoney 小写金额
    v_TransType 种类 -- 1: directly translate, 0: read it in words
    输出:大写金额
    ********************************************************/
    CREATE FUNCTION dbo.L2U (@n_LowerMoney numeric(15,2),@v_TransType int)
    RETURNS VARCHAR(200) AS
    BEGIN
    Declare @v_LowerStr VARCHAR(200) -- 小写金额
    Declare @v_UpperPart VARCHAR(200)
    Declare @v_UpperStr VARCHAR(200) -- 大写金额
    Declare @i_I int

    set @v_LowerStr = LTRIM(RTRIM(ROUND(@n_LowerMoney,2))) --四舍五入为指定的精度并删除数据左右空格
    set @i_I = 1
    set @v_UpperStr = ''

    while ( @i_I <= len(@v_LowerStr))
    begin
    select @v_UpperPart = case substring(@v_LowerStr,len(@v_LowerStr) - @i_I + 1,1)
    WHEN '.' THEN '元'
    WHEN '0' THEN '零'
    WHEN '1' THEN '壹'
    WHEN '2' THEN '贰'
    WHEN '3' THEN '叁'
    WHEN '4' THEN '肆'
    WHEN '5' THEN '伍'
    WHEN '6' THEN '陆'
    WHEN '7' THEN '柒'
    WHEN '8' THEN '捌'
    WHEN '9' THEN '玖'
    END
    +
    case @i_I
    WHEN 1 THEN '分'
    WHEN 2 THEN '角'
    WHEN 3 THEN ''
    WHEN 4 THEN ''
    WHEN 5 THEN '拾'
    WHEN 6 THEN '佰'
    WHEN 7 THEN '仟'
    WHEN 8 THEN '万'
    WHEN 9 THEN '拾'
    WHEN 10 THEN '佰'
    WHEN 11 THEN '仟'
    WHEN 12 THEN '亿'
    WHEN 13 THEN '拾'
    WHEN 14 THEN '佰'
    WHEN 15 THEN '仟'
    WHEN 16 THEN '万'
    ELSE ''
    END
    set @v_UpperStr = @v_UpperPart + @v_UpperStr
    set @i_I = @i_I + 1
    end

    if ( 0 = @v_TransType)
    begin
    set @v_UpperStr = REPLACE(@v_UpperStr,'零拾','零')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零佰','零')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零仟','零')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零零零','零')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零零','零')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零角零分','整')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零分','整')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零角','零')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零亿零万零元','亿元')
    set @v_UpperStr = REPLACE(@v_UpperStr,'亿零万零元','亿元')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零亿零万','亿')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零万零元','万元')
    set @v_UpperStr = REPLACE(@v_UpperStr,'万零元','万元')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零亿','亿')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零万','万')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零元','元')
    set @v_UpperStr = REPLACE(@v_UpperStr,'零零','零')
    end

    -- 对壹元以下的金额的处理
    if ( '元' = substring(@v_UpperStr,1,1))
    begin
    set @v_UpperStr = substring(@v_UpperStr,2,(len(@v_UpperStr) - 1))
    end

    if ( '零' = substring(@v_UpperStr,1,1))
    begin
    set @v_UpperStr = substring(@v_UpperStr,2,(len(@v_UpperStr) - 1))
    end

    if ( '角' = substring(@v_UpperStr,1,1))
    begin
    set @v_UpperStr = substring(@v_UpperStr,2,(len(@v_UpperStr) - 1))
    end

    if ( '分' = substring(@v_UpperStr,1,1))
    begin
    set @v_UpperStr = substring(@v_UpperStr,2,(len(@v_UpperStr) - 1))
    end

    if ('整' = substring(@v_UpperStr,1,1))
    begin
    set @v_UpperStr = '零元整'
    end
    return @v_UpperStr
    END

    例子:

    select dbo.L2U(56588441.111,0)

    select dbo.L2U(00.00,0)

  • 相关阅读:
    使用Boost Regex 的regex_search进行遍历搜索
    最全的libcurl库资源整理
    curl的http上传文件代码
    boost::property_tree读取解析ini文件--推荐
    UrlDecode
    C++、VC++、MFC网页自动注册、登陆、发帖、留言,QQ注册、QQ申请器源码、注册邮箱源码、自动发帖源码
    DUILIB入门简明教程
    MFC/VC CxImage 简单配置与使用 (完整版)
    几款国产开源的Windows界面库
    C++文件读写详解(ofstream,ifstream,fstream)
  • 原文地址:https://www.cnblogs.com/hxwzwiy/p/2418631.html
Copyright © 2011-2022 走看看