急!!请T-SQL前辈指点关于动态组装查询语句的错误

 所属目录:Java   |   类型:技术问答   |   时间:2007-05-21
 问题:

因为最近要帮助单位做一个2次开发,可是我手上没有数据字典,与此同时,后台数据库近2000个表,可是,多半都没有使用,因此,我就想把那些没有数据的表统统删除,即行数为0的表全部一次清除,为了实现这个过程,我的解决方案是如下:  
  1:先将所有用户自定义的表全部插入到一个新表之中:  
      代码如下:  
  create   table   teptable(tepid   smallint   identity(1,1),  
                                                tablename   varchar(116),  
                                        )  
  go  
   
  insert   into   teptable(tablename)  
  select   name  
  from   sysobjects  
  where   (type   =   u)   and   (xtype   =   u)  
  and   name   not   in(dtproperties,teptable)     --排除达芬奇工具用表和自身表2个用户表  
  go  
   
    这一步很顺利,所有的用户自定义表的名称都被插入到了新创建的表中,一共1670个用户表;  
   
  2.再创建一个表,并且将每个一个用户表的表的名称和表的列数插入到表中:  
  create   table   teptable01(tepid   smallint   identity(1,1),  
                                                tablename   varchar(116),  
                                                columnrows   int)  
  go  
  declare   @introws   int,  
                  @chvtablename   varchar(116),  
                  @intvalue   int,  
                  @chvquery   char(800)  
  select   @intvalue=min(tepid)  
  from     teptable  
   
  while   @intvalue   is   not   null  
  begin    
   
  select   @chvtablename=tablename  
  from   teptable  
  where   tepid=@intvalue  
   
  set   @chvquery=select   +@introws+=count(*)+   from   +@chvtablename+char(9)+print   @introws  
  print   @chvquery  
  exec(@chvquery)  
  print   @introws  
   
  insert   teptable01(tablename,columnrows)  
            values(@chvtablename,@introws)    
   
  select   @intvalue=min(tepid)  
  from   teptable  
  where   tepid>@intvalue  
   
  print   @chvtablename  
   
  end  
   
  在这里,我采用了while和min()循环来取值,按说,这是一个理想的解决方案,可是出问题出在这一行代码上:set   @chvquery=declare   @introws   int   select   +@introws+=count(*)+   from   +@chvtablename+char(9)+print   @introws  
  系统提示:服务器:   消息   245,级别   16,状态   1,行   20  
  将   varchar   值   declare   @introws   int   select     转换为数据类型为   int   的列时发生语法错误。  
  我实在不理解,我是动态组装一个查询语句,怎么会发生数据转换的问题?不理解。  
  于是我又修改了代码,完整如下:  
  create   table   teptable01(tepid   smallint   identity(1,1),  
                                                tablename   varchar(116),  
                                                columnrows   int)  
  go  
  declare   @introws   int,  
                  @chvtablename   varchar(116),  
                  @interrorcode   int,    
                  @intvalue   int,  
                  @chvquery   char(800)  
  select   @interrorcode=@@error  
   
  select   @intvalue=min(tepid)  
  from     teptable  
   
   
   
  while   @intvalue   is   not   null  
  begin    
   
  select   @chvtablename=tablename  
  from   teptable  
  where   tepid=@intvalue  
   
  set   @chvquery=declare   @introws   int   select   +@introws=count(*)+   from   +@chvtablename+char(9)+print   @introws  
  print   @chvquery  
  exec(@chvquery)  
   
   
  insert   teptable01(tablename,columnrows)  
            values(@chvtablename,@introws)    
   
  select   @intvalue=min(tepid)  
  from   teptable  
  where   tepid>@intvalue  
   
  print   @chvtablename  
   
  end  
   
  这一次,我主要修改了这里:  
  set   @chvquery=declare   @introws   int   select   +@introws=count(*)+   from   +@chvtablename+char(9)+print   @introws  
  根据print语句显示,执行都是正确的,可是,由于上面这一条语句声明的变量局限于这一个批处理,值传递不出来(要是可以声明全局变量该多好啊),结果,结果新创建的表中各个用户表的名称列倒是有了,可是最关键的列数却是空白,等于白费工夫,汗,其实,第二步大概可以用调用存储过程来实现,可是,这一块我不太熟悉,调用存储过程返回值的话,问题多多,请指点!关于第一次修改前的语句,我实在不明白,怎么动态组装涉及到了数据类型转换,这是为什么?  
  我的第三步就很简单了,删除新表中列数非0的记录,之后再利用动态组装查询把那些列数为0的表统统清除,这个代码很简单,就不写了,由于代码没有全部调试成功,所以,调试语句、事务语句、错误处理语句我都没有写,就写点核心代码,请指点,谢谢!  
  其实,我还在set语句内部试验过select……into语句,结果提示说:select赋值语句不得与搜索语句同时使用,汗,又失败了。我也知道有其他解决方案能取得每个用户表的行数,可我就想依托这一种解决方案.  
 

· 网友精彩回答:

发表者:paoluo

试试  
   
  create   table   teptable01(tepid   smallint   identity(1,1),  
                                                tablename   varchar(116),  
                                                columnrows   int)  
  go  
  declare   @introws   int,  
                  @chvtablename   varchar(116),  
                  @intvalue   int,  
                  @chvquery   nvarchar(4000)  
  --                 @chvquery   char(800)  
   
  select   @intvalue=min(tepid)  
  from     teptable  
   
  while   @intvalue   is   not   null  
  begin    
   
  select   @chvtablename=tablename  
  from   teptable  
  where   tepid=@intvalue  
   
  --set   @chvquery=select   +@introws+=count(*)+   from   +@chvtablename+char(9)+print   @introws  
  set   @chvquery=nselect   +@introws   =count(*)+   from   +@chvtablename  
  print   @chvquery  
  --exec(@chvquery)  
  exec   sp_executesql   @chvquery,n@introws   int   output,@introws   output  
  print   @introws  
   
  insert   teptable01(tablename,columnrows)  
            values(@chvtablename,@introws)    
   
  select   @intvalue=min(tepid)  
  from   teptable  
  where   tepid>@intvalue  
   
  print   @chvtablename  
   
  end

发表者:libin_ftsafe

set   nocount   on  
   
  declare   @s   varchar(8000),@name   varchar(100)  
   
  declare   t_cursor   cursor   for    
  select    
          name  
  from    
          sysobjects  
  where    
          type   =   u    
          and    
          xtype   =   u  
          and    
          name   !=   dtproperties  
   
  open   t_cursor  
   
  fetch   next   from   t_cursor   into   @name  
   
  while   @@fetch_status   =   0  
  begin  
          set   @s   =   if   not   exists(select   1   from   +@name+)           drop   table   +@name  
          print   @s  
          exec(@s)  
          fetch   next   from   t_cursor   into   @name  
  end  
  close   t_cursor  
  deallocate   t_cursor  
   
  set   nocount   off

发表者:ddcata

我是群里的.  
  改那一段改成如下:  
  set   @chvquery=select   ++@introws++=count(*)+   from   +@chvtablename+char(9)+print   @introws  
  print   @chvquery  
  exec(@chvquery)  
  print   @introws  
   
  就可以了  
   
   
  另:  
  欢迎加入技术群:12659949   进行讨论  
 

.
处理 SSI 文件时出错
© 2006-2008 All Rights Reserved