精妙的SQL和SQL SERVER 与ACCESS、EXCEL的数据导入导出转换

今天做个行列转换 找到的好语句  解决了我的问题
     *  说明:复制表(只复制结构,源表名:a 新表名:b)
      
select   *   into  b  from  a  where   1 <> 1

    
*  说明:拷贝表(拷贝数据,源表名:a 目标表名:b)
      
insert   into  b(a, b, c)  select  d,e,f  from  b;

    
*  说明:显示文章、提交人和最后回复时间
      
select  a.title,a.username,b.adddate  from   table  a,( select   max (adddate) adddate  from   table   where   table .title = a.title) b

    
*  说明:外连接查询(表名1:a 表名2:b)
      
select  a.a, a.b, a.c, b.c, b.d, b.f  from  a  LEFT  OUT  JOIN  b  ON  a.a  =  b.c

    
*  说明:日程安排提前五分钟提醒
      
select   *   from  日程安排  where   datediff ( ' minute ' ,f开始时间, getdate ()) > 5

    
*  说明:两张关联表,删除主表中已经在副表中没有的信息
      
delete   from  info  where   not   exists  (  select   *   from  infobz  where  info.infid = infobz.infid )

    
*  说明: --

      SQL:

      
SELECT  A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE

      
FROM  TABLE1,

      (
SELECT  X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE

      
FROM  ( SELECT  NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND

      
FROM  TABLE2

      
WHERE  TO_CHAR(UPD_DATE, ' YYYY/MM ' =  TO_CHAR(SYSDATE,  ' YYYY/MM ' )) X,

      (
SELECT  NUM, UPD_DATE, STOCK_ONHAND

      
FROM  TABLE2

      
WHERE  TO_CHAR(UPD_DATE, ' YYYY/MM ' =

      TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 
' YYYY/MM ' ||   ' /01 ' , ' YYYY/MM/DD ' -   1 ' YYYY/MM ' ) ) Y,

      
WHERE  X.NUM  =  Y.NUM ( +

      
AND  X.INBOUND_QTY  +  NVL(Y.STOCK_ONHAND, 0 <>  X.STOCK_ONHAND ) B

      
WHERE  A.NUM  =  B.NUM

    
*  说明: --
       select   *   from  studentinfo  where   not   exists ( select   *   from  student  where  studentinfo.id = student.id)  and  系名称 = ' "&strdepartmentname&" '   and  专业名称 = ' "&strprofessionname&" '   order   by  性别,生源地,高考总成绩

    
*  从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源)

      
SELECT  a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate,  ' yyyy ' AS  telyear,

      
SUM (decode(TO_CHAR(a.telfeedate,  ' mm ' ),  ' 01 ' , a.factration))  AS  JAN,

      
SUM (decode(TO_CHAR(a.telfeedate,  ' mm ' ),  ' 02 ' , a.factration))  AS  FRI,

      
SUM (decode(TO_CHAR(a.telfeedate,  ' mm ' ),  ' 03 ' , a.factration))  AS  MAR,

      
SUM (decode(TO_CHAR(a.telfeedate,  ' mm ' ),  ' 04 ' , a.factration))  AS  APR,

      
SUM (decode(TO_CHAR(a.telfeedate,  ' mm ' ),  ' 05 ' , a.factration))  AS  MAY,

      
SUM (decode(TO_CHAR(a.telfeedate,  ' mm ' ),  ' 06 ' , a.factration))  AS  JUE,

      
SUM (decode(TO_CHAR(a.telfeedate,  ' mm ' ),  ' 07 ' , a.factration))  AS  JUL,

      
SUM (decode(TO_CHAR(a.telfeedate,  ' mm ' ),  ' 08 ' , a.factration))  AS  AGU,

      
SUM (decode(TO_CHAR(a.telfeedate,  ' mm ' ),  ' 09 ' , a.factration))  AS  SEP,

      
SUM (decode(TO_CHAR(a.telfeedate,  ' mm ' ),  ' 10 ' , a.factration))  AS  OCT,

      
SUM (decode(TO_CHAR(a.telfeedate,  ' mm ' ),  ' 11 ' , a.factration))  AS  NOV,

      
SUM (decode(TO_CHAR(a.telfeedate,  ' mm ' ),  ' 12 ' , a.factration))  AS   DEC

      
FROM  ( SELECT  a.userper, a.tel, a.standfee, b.telfeedate, b.factration

      
FROM  TELFEESTAND a, TELFEE b

      
WHERE  a.tel  =  b.telfax) a

      
GROUP   BY  a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate,  ' yyyy ' )

    
*  说明:四表联查问题
      
select   *   from  a  left   inner   join  b  on  a.a = b.b  right   inner   join  c  on  a.a = c.c  inner   join  d  on  a.a = d.d  where  ..

    
*  说明:得到表中最小的未使用的ID号

    
*   SELECT  ( CASE   WHEN   EXISTS ( SELECT   *   FROM  Handle b  WHERE  b.HandleID  =   1 THEN   MIN (HandleID)  +   1   ELSE   1   END as  HandleID   FROM  Handle  WHERE   NOT  HandleID  IN  ( SELECT  a.HandleID  -   1   FROM  Handle a)

    
*  一个SQL语句的问题:行列转换
      
select   *   from  v_temp
      上面的视图结果如下:
      
user_name  role_name
      
-- -----------------------
      系统管理员 管理员
      feng 管理员
      feng 一般用户
      test 一般用户
      想把结果变成这样:
      
user_name  role_name
      
-- -------------------------
      系统管理员 管理员
      feng 管理员,一般用户
      test 一般用户
      
===================
      
create   table  a_test(name  varchar ( 20 ),role2  varchar ( 20 ))
      
insert   into  a_test  values ( ' ' , ' 管理员 ' )
      
insert   into  a_test  values ( ' ' , ' 管理员 ' )
      
insert   into  a_test  values ( ' ' , ' 一般用户 ' )
      
insert   into  a_test  values ( ' ' , ' 一般用户 ' )

      
create   function  join_str( @content   varchar ( 100 ))
      
returns   varchar ( 2000 )
      
as
      
begin
      
declare   @str   varchar ( 2000 )
      
set   @str = ''
      
select   @str = @str + ' , ' + rtrim (role2)  from  a_test  where   [ name ] = @content
      
select   @str = right ( @str , len ( @str ) - 1 )
      
return   @str
      
end
      
go

      
-- 调用:
       select   [ name ] ,dbo.join_str( [ name ] ) role2  from  a_test  group   by   [ name ]

      
-- select distinct name,dbo.uf_test(name) from a_test

    
*  快速比较结构相同的两表
      结构相同的两表,一表有记录3万条左右,一表有记录2万条左右,我怎样快速查找两表的不同记录?
      
============================
      给你一个测试方法,从northwind中的orders表取数据。
      
select   *   into  n1  from  orders
      
select   *   into  n2  from  orders

      
select   *   from  n1
      
select   *   from  n2

      
-- 添加主键,然后修改n1中若干字段的若干条
       alter   table  n1  add   constraint  pk_n1_id  primary   key  (OrderID)
      
alter   table  n2  add   constraint  pk_n2_id  primary   key  (OrderID)

      
select  OrderID  from  ( select   *   from  n1  union   select   *   from  n2) a  group   by  OrderID  having   count ( * >   1

      应该可以,而且将不同的记录的ID显示出来。
      下面的适用于双方记录一样的情况,

      
select   *   from  n1  where  orderid  in  ( select  OrderID  from  ( select   *   from  n1  union   select   *   from  n2) a  group   by  OrderID  having   count ( * >   1 )
      至于双方互不存在的记录是比较好处理的
      
-- 删除n1,n2中若干条记录
       delete   from  n1  where  orderID  in  ( ' 10728 ' , ' 10730 ' )
      
delete   from  n2  where  orderID  in  ( ' 11000 ' , ' 11001 ' )

      
-- *************************************************************
       --  双方都有该记录却不完全相同
       select   *   from  n1  where  orderid  in ( select  OrderID  from  ( select   *   from  n1  union   select   *   from  n2) a  group   by  OrderID  having   count ( * >   1 )
      
union
      
-- n2中存在但在n1中不存的在10728,10730
       select   *   from  n1  where  OrderID  not   in  ( select  OrderID  from  n2)
      
union
      
-- n1中存在但在n2中不存的在11000,11001
       select   *   from  n2  where  OrderID  not   in  ( select  OrderID  from  n1)

    
*  四种方法取表里n到m条纪录:

      
1 .
      
select   top  m  *   into  临时表(或表变量)  from  tablename  order   by  columnname  --  将top m笔插入
       set   rowcount  n
      
select   *   from  表变量  order   by  columnname  desc


      
2 .
      
select   top  n  *   from  ( select   top  m  *   from  tablename  order   by  columnname) a  order   by  columnname  desc


      
3 .如果tablename里没有其他identity列,那么:
      
select   identity ( int ) id0, *   into  # temp   from  tablename

      取n到m条的语句为:
      
select   *   from  # temp   where  id0  >= and  id0  <=  m

      如果你在执行select 
identity ( int ) id0, *   into  # temp   from  tablename这条语句的时候报错,那是因为你的DB中间的select  into / bulkcopy属性没有打开要先执行:
      
exec  sp_dboption 你的DB名字, ' select into/bulkcopy ' ,true


      
4 .如果表里有identity属性,那么简单:
      
select   *   from  tablename  where   identitycol   between  n  and  m

    
*  如何删除一个表中重复的记录?
      
create   table  a_dist(id  int ,name  varchar ( 20 ))

      
insert   into  a_dist  values ( 1 , ' abc ' )
      
insert   into  a_dist  values ( 1 , ' abc ' )
      
insert   into  a_dist  values ( 1 , ' abc ' )
      
insert   into  a_dist  values ( 1 , ' abc ' )

      
exec  up_distinct  ' a_dist ' , ' id '

      
select   *   from  a_dist

      
create   procedure  up_distinct( @t_name   varchar ( 30 ), @f_key   varchar ( 30 ))
      
-- f_key表示是分组字段﹐即主键字段
       as
      
begin
      
declare   @max   integer , @id   varchar ( 30 ) , @sql   varchar ( 7999 ) , @type   integer
      
select   @sql   =   ' declare cur_rows cursor for select  ' + @f_key + '  ,count(*) from  '   + @t_name   + '  group by  '   + @f_key   + '  having count(*) > 1 '
      
exec ( @sql )
      
open  cur_rows
      
fetch  cur_rows  into   @id , @max
      
while   @@fetch_status = 0
      
begin
      
select   @max   =   @max   - 1
      
set   rowcount   @max
      
select   @type   =  xtype  from  syscolumns  where  id = object_id ( @t_name and  name = @f_key
      
if   @type = 56
      
select   @sql   =   ' delete from  ' + @t_name + '  where  '   +   @f_key + '  =  ' +   @id
      
if   @type = 167
      
select   @sql   =   ' delete from  ' + @t_name + '  where  '   +   @f_key + '  =  ' + '''' +   @id   + ''''
      
exec ( @sql )
      
fetch  cur_rows  into   @id , @max
      
end
      
close  cur_rows
      
deallocate  cur_rows
      
set   rowcount   0
      
end

      
select   *   from  systypes
      
select   *   from  syscolumns  where  id  =   object_id ( ' a_dist ' )

    
*  查询数据的最大排序问题(只能用一条语句写)
      
CREATE   TABLE  hard (qu  char  ( 11 ) ,co  char  ( 11 ) ,je numeric( 3 0 ))

      
insert   into  hard  values  ( ' A ' , ' 1 ' , 3 )
      
insert   into  hard  values  ( ' A ' , ' 2 ' , 4 )
      
insert   into  hard  values  ( ' A ' , ' 4 ' , 2 )
      
insert   into  hard  values  ( ' A ' , ' 6 ' , 9 )
      
insert   into  hard  values  ( ' B ' , ' 1 ' , 4 )
      
insert   into  hard  values  ( ' B ' , ' 2 ' , 5 )
      
insert   into  hard  values  ( ' B ' , ' 3 ' , 6 )
      
insert   into  hard  values  ( ' C ' , ' 3 ' , 4 )
      
insert   into  hard  values  ( ' C ' , ' 6 ' , 7 )
      
insert   into  hard  values  ( ' C ' , ' 2 ' , 3 )


      要求查询出来的结果如下:

      qu co je
      
-- --------- ----------- -----
      A  6   9
      A 
2   4
      B 
3   6
      B 
2   5
      C 
6   7
      C 
3   4


      就是要按qu分组,每组中取je最大的前2位!!
      而且只能用一句sql语句!!!
      
select   *   from  hard a  where  je  in  ( select   top   2  je  from  hard b  where  a.qu = b.qu  order   by  je)

    
*  求删除重复记录的sql语句?
      怎样把具有相同字段的纪录删除,只留下一条。
      例如,表test里有id,name字段
      如果有name相同的记录 只留下一条,其余的删除。
      name的内容不定,相同的记录数不定。
      有没有这样的sql语句?
      
==============================
      A:一个完整的解决方案:

      将重复的记录记入temp1表:
      
select   [ 标志字段id ] , count ( * into  temp1  from   [ 表名 ]
      
group   by   [ 标志字段id ]
      
having   count ( * ) > 1

      
2 、将不重复的记录记入temp1表:
      
insert  temp1  select   [ 标志字段id ] , count ( * from   [ 表名 ]   group   by   [ 标志字段id ]   having   count ( * ) = 1

      
3 、作一个包含所有不重复记录的表:
      
select   *   into  temp2  from   [ 表名 ]   where  标志字段id  in ( select  标志字段id  from  temp1)

      
4 、删除重复表:
      
delete   [ 表名 ]

      
5 、恢复表:
      
insert   [ 表名 ]   select   *   from  temp2

      
6 、删除临时表:
      
drop   table  temp1
      
drop   table  temp2
      
================================
      B:
      
create   table  a_dist(id  int ,name  varchar ( 20 ))

      
insert   into  a_dist  values ( 1 , ' abc ' )
      
insert   into  a_dist  values ( 1 , ' abc ' )
      
insert   into  a_dist  values ( 1 , ' abc ' )
      
insert   into  a_dist  values ( 1 , ' abc ' )

      
exec  up_distinct  ' a_dist ' , ' id '

      
select   *   from  a_dist

      
create   procedure  up_distinct( @t_name   varchar ( 30 ), @f_key   varchar ( 30 ))
      
-- f_key表示是分组字段﹐即主键字段
       as
      
begin
      
declare   @max   integer , @id   varchar ( 30 ) , @sql   varchar ( 7999 ) , @type   integer
      
select   @sql   =   ' declare cur_rows cursor for select  ' + @f_key + '  ,count(*) from  '   + @t_name   + '  group by  '   + @f_key   + '  having count(*) > 1 '
      
exec ( @sql )
      
open  cur_rows
      
fetch  cur_rows  into   @id , @max
      
while   @@fetch_status = 0
      
begin
      
select   @max   =   @max   - 1
      
set   rowcount   @max
      
select   @type   =  xtype  from  syscolumns  where  id = object_id ( @t_name and  name = @f_key
      
if   @type = 56
      
select   @sql   =   ' delete from  ' + @t_name + '  where  '   +   @f_key + '  =  ' +   @id
      
if   @type = 167
      
select   @sql   =   ' delete from  ' + @t_name + '  where  '   +   @f_key + '  =  ' + '''' +   @id   + ''''
      
exec ( @sql )
      
fetch  cur_rows  into   @id , @max
      
end
      
close  cur_rows
      
deallocate  cur_rows
      
set   rowcount   0
      
end

      
select   *   from  systypes
      
select   *   from  syscolumns  where  id  =   object_id ( ' a_dist ' )

    
*  行列转换 -- 普通

      假设有张学生成绩表(CJ)如下
      Name Subject Result
      张三 语文 
80
      张三 数学 
90
      张三 物理 
85
      李四 语文 
85
      李四 数学 
92
      李四 物理 
82

      想变成
      姓名 语文 数学 物理
      张三 
80   90   85
      李四 
85   92   82

      
declare   @sql   varchar ( 4000 )
      
set   @sql   =   ' select Name '
      
select   @sql   =   @sql   +   ' ,sum(case Subject when  ''' + Subject + '''  then Result end) [ ' + Subject + ' ] '
      
from  ( select   distinct  Subject  from  CJ)  as  a
      
select   @sql   =   @sql + '  from test group by name '
      
exec ( @sql )

      行列转换
-- 合并

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

      创建一个合并的函数
      
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

    
*  如何取得一个数据表的所有列名

      方法如下:先从SYSTEMOBJECT系统表中取得数据表的SYSTEMID,然后再SYSCOLUMN表中取得该数据表的所有列名。
      SQL语句如下:
      
declare   @objid   int , @objname   char ( 40 )
      
set   @objname   =   ' tablename '
      
select   @objid   =  id  from  sysobjects  where  id  =   object_id ( @objname )
      
select   ' Column_name '   =  name  from  syscolumns  where  id  =   @objid   order   by  colid

      或

      
SELECT   *   FROM  INFORMATION_SCHEMA.COLUMNS  WHERE  TABLE_NAME  = ' users '

    
*  通过SQL语句来更改用户的密码

      修改别人的,需要sysadmin role
      
EXEC  sp_password  NULL ' newpassword ' ' User '

      如果帐号为SA执行EXEC sp_password 
NULL ' newpassword ' , sa

    
*  怎么判断出一个表的哪些字段不允许为空?

      
select  COLUMN_NAME  from  INFORMATION_SCHEMA.COLUMNS  where  IS_NULLABLE = ' NO '   and  TABLE_NAME = tablename

    
*  如何在数据库里找到含有相同字段的表?
      a. 查已知列名的情况
      
SELECT  b.name  as  TableName,a.name  as  columnname
      
From  syscolumns a  INNER   JOIN  sysobjects b
      
ON  a.id = b.id
      
AND  b.type = ' U '
      
AND  a.name = ' 你的字段名字 '

    
*  未知列名查所有在不同表出现过的列名
      
Select  o.name  As  tablename,s1.name  As  columnname
      
From  syscolumns s1, sysobjects o
      
Where  s1.id  =  o.id
      
And  o.type  =   ' U '
      
And   Exists  (
      
Select   1   From  syscolumns s2
      
Where  s1.name  =  s2.name
      
And  s1.id  <>  s2.id
      )

    
*  查询第xxx行数据

      假设id是主键:
      
select   *   from  ( select   top  xxx  *   from  yourtable) aa  where   not   exists ( select   1   from  ( select   top  xxx - 1   *   from  yourtable) bb  where  aa.id = bb.id)

      如果使用游标也是可以的
      
fetch  absolute  [ number ]   from   [ cursor_name ]
      行数为绝对行数

    
*  SQL Server日期计算
      a. 一个月的第一天
      
SELECT   DATEADD (mm,  DATEDIFF (mm, 0 , getdate ()),  0 )
      b. 本周的星期一
      
SELECT   DATEADD (wk,  DATEDIFF (wk, 0 , getdate ()),  0 )
      c. 一年的第一天
      
SELECT   DATEADD (yy,  DATEDIFF (yy, 0 , getdate ()),  0 )
      d. 季度的第一天
      
SELECT   DATEADD (qq,  DATEDIFF (qq, 0 , getdate ()),  0 )
      e. 上个月的最后一天
      
SELECT   dateadd (ms, - 3 , DATEADD (mm,  DATEDIFF (mm, 0 , getdate ()),  0 ))
      f. 去年的最后一天
      
SELECT   dateadd (ms, - 3 , DATEADD (yy,  DATEDIFF (yy, 0 , getdate ()),  0 ))
      g. 本月的最后一天
      
SELECT   dateadd (ms, - 3 , DATEADD (mm,  DATEDIFF (m, 0 , getdate ()) + 1 0 ))
      h. 本月的第一个星期一
      
select   DATEADD (wk,  DATEDIFF (wk, 0 ,
      
dateadd (dd, 6 - datepart ( day , getdate ()), getdate ())
      ), 
0 )
      i. 本年的最后一天
      
SELECT   dateadd (ms, - 3 , DATEADD (yy,  DATEDIFF (yy, 0 , getdate ()) + 1 0 ))。

    
*  获取表结构 [ 把 'sysobjects' 替换 成 'tablename' 即可 ]

      
SELECT   CASE   IsNull (I.name,  '' )
      
When   ''   Then   ''
      
Else   ' * '
      
End   as  IsPK,
      
Object_Name (A.id)  as  t_name,
      A.name 
as  c_name,
      
IsNull ( SubString (M. text 1 254 ),  '' as  pbc_init,
      T.name 
as  F_DataType,
      
CASE   IsNull ( TYPEPROPERTY (T.name,  ' Scale ' ),  '' )
      
WHEN   ''   Then   Cast (A.prec  as   varchar )
      
ELSE   Cast (A.prec  as   varchar +   ' , '   +   Cast (A.scale  as   varchar )
      
END   as  F_Scale,
      A.isnullable 
as  F_isNullAble
      
FROM  Syscolumns  as  A
      
JOIN  Systypes  as  T
      
ON  (A.xType  =  T.xUserType  AND  A.Id  =   Object_id ( ' sysobjects ' ) )
      
LEFT   JOIN  ( SysIndexes  as  I
      
JOIN  Syscolumns  as  A1
      
ON  ( I.id  =  A1.id  and  A1.id  =   object_id ( ' sysobjects ' and  (I.status  &   0x800 =   0x800   AND  A1.colid  <=  I.keycnt) )
      
ON  ( A.id  =  I.id  AND  A.name  =   index_col ( ' sysobjects ' , I.indid, A1.colid) )
      
LEFT   JOIN  SysComments  as  M
      
ON  ( M.id  =  A.cdefault  and   ObjectProperty (A.cdefault,  ' IsConstraint ' =   1  )
      
ORDER   BY  A.Colid  ASC

    
*  提取数据库内所有表的字段详细说明的SQL语句

      
SELECT
      (
case   when  a.colorder = 1   then  d.name  else   ''   end ) N ' 表名 ' ,
      a.colorder N
' 字段序号 ' ,
      a.name N
' 字段名 ' ,
      (
case   when   COLUMNPROPERTY ( a.id,a.name, ' IsIdentity ' ) = 1   then   ' ' else   ''
      
end ) N ' 标识 ' ,
      (
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 ) N ' 主键 ' ,
      b.name N
' 类型 ' ,
      a.length N
' 占用字节数 ' ,
      
COLUMNPROPERTY (a.id,a.name, ' PRECISION ' as  N ' 长度 ' ,
      
isnull ( COLUMNPROPERTY (a.id,a.name, ' Scale ' ), 0 as  N ' 小数位数 ' ,
      (
case   when  a.isnullable = 1   then   ' ' else   ''   end ) N ' 允许空 ' ,
      
isnull (e. text , '' ) N ' 默认值 ' ,
      
isnull (g. [ value ] , '' AS  N ' 字段说明 '
      
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   object_name (a.id),a.colorder

    
*  快速获取表test的记录总数 [ 对大容量表非常有效 ]

      快速获取表test的记录总数:
      
select  rows  from  sysindexes  where  id  =   object_id ( ' test ' and  indid  in  ( 0 , 1 )

      
update   2   set  KHXH = (ID + 1 )\ 2  2行递增编号
      
update   [ 23 ]   set  id1  =   ' No. ' + right ( ' 00000000 ' + id, 6 where  id  not   like   ' No% '   // 递增
      
update   [ 23 ]   set  id1 =   ' No. ' + right ( ' 00000000 ' + replace (id1, ' No. ' , '' ), 6 // 补位递增
      
delete   from   [ 1 ]   where  (id % 2 ) = 1
      奇数

    
*  替换表名字段
      
update   [ 1 ]   set  domurl  =   replace (domurl, ' Upload/Imgswf/ ' , ' Upload/Photo/ ' where  domurl  like   ' %Upload/Imgswf/% '

    
*  截位
      
SELECT   LEFT (表名,  5 )
熟悉SQL SERVER 2000的数据库管理员都知道,其DTS可以进行数据的导入导出,其实,我们也可以使用Transact - SQL语句进行导入导出操作。在 Transact - SQL语句中,我们主要使用OpenDataSource函数、 OPENROWSET  函数,关于函数的详细说明,请参考SQL联机帮助。利用下述方法,可以十分容易地实现SQL SERVER、ACCESS、EXCEL数据转换,详细说明如下:

一、SQL SERVER 和ACCESS的数据导入导出

常规的数据导入导出:
使用DTS向导迁移你的Access数据到SQL Server,你可以使用这些步骤:
  ○1在SQL SERVER企业管理器中的Tools(工具)菜单上,选择Data Transformation
  ○2Services(数据转换服务),然后选择  czdImport Data(导入数据)。
  ○3在Choose a Data Source(选择数据源)对话框中选择Microsoft Access 
as  the Source,然后键入你的.mdb数据库(.mdb文件扩展名)的文件名或通过浏览寻找该文件。
  ○4在Choose a Destination(选择目标)对话框中,选择Microsoft OLE DB Prov ider 
for  SQL Server,选择数据库服务器,然后单击必要的验证方式。
  ○5在Specify 
Table  Copy(指定表格复制)或Query(查询)对话框中,单击Copy tables(复制表格)。
    ○6在Select Source Tables(选择源表格)对话框中,单击Select 
All (全部选定)。下一步,完成。

Transact
- SQL语句进行导入导出:
1 .在SQL SERVER里查询access数据:

SELECT   *   FROM   OpenDataSource ' Microsoft.Jet.OLEDB.4.0 ' , ' Data Source="c:\DB.mdb";User ID=Admin;Password= ' )表名

2 .将access导入SQL server
在SQL SERVER 里运行:
SELECT   *   INTO  newtable  FROM   OPENDATASOURCE  ( ' Microsoft.Jet.OLEDB.4.0 ' , ' Data Source="c:\DB.mdb";User ID=Admin;Password= '  )表名

3 .将SQL SERVER表里的数据插入到Access表中
在SQL SERVER 里运行:
insert   into   OpenDataSource ' Microsoft.Jet.OLEDB.4.0 ' , ' Data Source=" c:\DB.mdb";User ID=Admin;Password= ' )表名 (列名1,列名2)  select  列名1,列名2   from   sql表

实例:
insert   into    OPENROWSET ( ' Microsoft.Jet.OLEDB.4.0 ' , ' C:\db.mdb ' ; ' admin ' ; '' , Test)  select  id,name  from  Test


INSERT   INTO   OPENROWSET ( ' Microsoft.Jet.OLEDB.4.0 ' ' c:\trade.mdb ' ' admin ' '' , 表名)  SELECT   *   FROM  sqltablename

二、SQL SERVER 和EXCEL的数据导入导出

1 、在SQL SERVER里查询Excel数据:

SELECT   *   FROM   OpenDataSource ' Microsoft.Jet.OLEDB.4.0 ' , ' Data Source="c:\book1.xls";User ID=Admin;Password=;Extended properties=Excel 5.0 ' ) [ Sheet1$ ]

下面是个查询的示例,它通过用于 Jet 的 OLE DB 提供程序查询 Excel 电子表格。
SELECT   *   FROM   OpenDataSource  (  ' Microsoft.Jet.OLEDB.4.0 ' , ' Data Source="c:\Finance\account.xls";User ID=Admin;Password=;Extended properties=Excel 5.0 ' )xactions

2 、将Excel的数据导入SQL server :
SELECT   *   into  newtable  FROM   OpenDataSource ' Microsoft.Jet.OLEDB.4.0 ' , ' Data Source="c:\book1.xls";User ID=Admin;Password=;Extended properties=Excel 5.0 ' ) [ Sheet1$ ]

实例:
SELECT   *   into  newtable  FROM   OpenDataSource ' Microsoft.Jet.OLEDB.4.0 ' , ' Data Source="c:\Finance\account.xls";User ID=Admin;Password=;Extended properties=Excel 5.0 ' )xactions

3 、将SQL SERVER中查询到的数据导成一个Excel文件
T
- SQL代码:
EXEC  master..xp_cmdshell  ' bcp 库名.dbo.表名out c:\Temp.xls -c -q -S"servername" -U"sa" -P"" '
参数:S 是SQL服务器名;U是用户;P是密码
说明:还可以导出文本文件等多种格式

实例:
EXEC  master..xp_cmdshell  ' bcp saletesttmp.dbo.CusAccount out c:\temp1.xls -c -q -S"pmserver" -U"sa" -P"sa" '

EXEC  master..xp_cmdshell  ' bcp "SELECT au_fname, au_lname FROM pubs..authors ORDER BY au_lname" queryout C:\ authors.xls -c -Sservername -Usa -Ppassword '

在VB6中应用ADO导出EXCEL文件代码:
Dim cn  
As  New ADODB.Connection
cn.
open  "Driver = {SQL Server};Server = WEBSVR; DataBase = WebMis;UID = sa;WD = 123 ;"
cn.
execute  "master..xp_cmdshell  ' bcp "SELECT col1, col2 FROM 库名.dbo.表名" queryout E:\DT.xls -c -Sservername -Usa -Ppassword ' "


4 、在SQL SERVER里往Excel插入数据:

insert   into   OpenDataSource ' Microsoft.Jet.OLEDB.4.0 ' , ' Data Source="c:\Temp.xls";User ID=Admin;Password=;Extended properties=Excel 5.0 ' )table1 (A1,A2,A3)  values  ( 1 , 2 , 3 )

T
- SQL代码:
INSERT   INTO  
 
OPENDATASOURCE ( ' Microsoft.JET.OLEDB.4.0 ' , ' Extended Properties=Excel 8.0;Data source=C:\training\inventur.xls ' ) [ Filiale1$ ]   (bestand, produkt)  VALUES  ( 20 ' Test '

总结:利用以上语句,我们可以方便地将SQL SERVER、ACCESS和EXCEL电子表格软件中的数据进行转换,为我们提供了极大方便!

你可能感兴趣的:(精妙的SQL和SQL SERVER 与ACCESS、EXCEL的数据导入导出转换)