时间:2010-08-13 | 栏目:数据库综合 | 点击:次
最近在写一个升级程序,其中要求将一个旧数据库里面的所有的照片都转到新数据库。暂且把旧数据库叫OldDB,新数据库叫NewDB,新数据库里面的字段为【Photo】,旧数据库叫【Picture】 。开始我是这样做的,先读出旧数据库里的数据,然后用insert into插入:
insert into[ table1] values("&rs("Picture")&")
后来发现不行,我以为数据类型搞错了,改了下代码,如下:
insert into[ table1] values(‘"&rs("Picture")&"’)
多加了一对单引号,系统还是提示错误。以下为存储过程:
<CENTER><ccid_nobr>
<table width="400" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center">
<tr>
    <td bgcolor="e6e6e6" class="code" style="font-size:9pt">
    <pre><ccid_code>
if exists (select * from dbo.sysobjects 
where id = object_id(N'[dbo].[sp_textcopy]') 
and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_textcopy]
GO
SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS OFF 
GO
CREATE PROCEDURE sp_textcopy (
  @srvname    varchar (30),
  @login varchar (30),
  @password    varchar (30),
  @dbname varchar (30),
  @tbname varchar (30),
  @colname    varchar (30),
  @filename    varchar (30),
  @whereclause varchar (40),
  @direction  char(1))
AS
DECLARE @exec_str varchar (255)
SELECT @exec_str =
   'textcopy /S ' + @srvname +
   ' /U ' + @login +
   ' /P ' + @password +
   ' /D ' + @dbname +
   ' /T ' + @tbname +
   ' /C ' + @colname +
   ' /W "' + @whereclause +
   '" /F ' + @filename +
   ' /' + @direction
EXEC master..xp_cmdshell @exec_str
GO
SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO
  </ccid_code></pre> 
   </td>
  </tr>
</table>
</ccid_nobr></CENTER> 
这是调用textcopy将图片数据导入和导出的语句,我原打算新旧数据库调用同一个存储过程,旧数据库先将数据导出到硬盘,新数据库在导入。在测试以后,发现不成功,页面显示不出数据,单独用textcopy测试还是可以导出数据的,但在程序中调用,没有成功。我接下来换成下面的存储过程:
<CENTER><ccid_nobr>
<table width="400" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center">
<tr>
    <td bgcolor="e6e6e6" class="code" style="font-size:9pt">
    <pre><ccid_code> 
 
if exists (select * from dbo.sysobjects 
where id = object_id(N'[dbo].[sp_imageio]') 
and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_imageio]
GO
SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS OFF 
GO
Create   proc   p_binaryIO   
  @servename   varchar   (30),
--服务器名称   
  @username   varchar   (30),   
--用户名   
  @password   varchar   (30), 
--密码   
  @tbname   varchar   (500),   
--数据库..表名   
  @fdname   varchar   (30),   
--字段名   
  @fname   varchar   (1000), 
--目录+文件名,处理过程中要使用/覆盖:@filename+_temp   
  @tj   varchar   (1000)='',   
--处理条件.对于数据导入,如果条件中包含@fdname,请指定表名前缀   
  @isout   bit=1 --1导出((默认),0导入   
  AS
  declare   @fname_in   varchar(1000) 
--bcp处理应答文件名   
  ,@fsize   varchar(20) 
--要处理的文件的大小   
  ,@m_tbname   varchar(50) 
--临时表名   
  ,@sql   varchar(8000)   
    
  --则取得导入文件的大小   
  if   @isout=1
  set   @fsize='0'   
  else   
  begin   
  create   table   #tb(可选名   
varchar(20),大小   int   
  ,创建日期   varchar(10),创建时间   
varchar(20)   
  ,上次写操作日期   varchar(10),
上次写操作时间   varchar(20)   
  ,上次访问日期   varchar(10),
上次访问时间   varchar(20),特性   int)   
  insert   into   #tb   
  exec   master..xp_getfiledetails   @fname   
  select   @fsize=大小   from   #tb   
  drop   table   #tb   
  if   @fsize   is   null   
  begin   
  print   '文件未找到'   
  return   
  end   
    
  end   
    
  --生成数据处理应答文件   
  set   @m_tbname='
[##temp'+cast(newid()   as   varchar(40))+']'   
  set   @sql='select   *   into      from(   
  select   null   as   类型   
  union   all   select   0   as   前缀   
  union   all   select      as   长度   
  union   all   select   null   as   结束   
  union   all   select   null   as   格式   
  )   a'   
  exec(@sql)   
  select   @fname_in=@fname+'_temp'   
  ,@sql='bcp   ""   out   "   
  +'"   /S"   
  +case   when   isnull(@username,'')=''   then   ''
  else   '"   /U"   end   
  +'"   /P"'+isnull(@password,'')+'"   /c'   
  exec   master..xp_cmdshell   @sql   
  --删除临时表   
  set   @sql='drop   table      
  exec(@sql)   
    
  if   @isout=1   
  begin   
  set   @sql='bcp   "select   top   1      from   '
     isnull(@tj,'')   when   ''   then   ''   
  else   '   where      end   
  +'"   queryout   "   
  +'"   /S"   
  +case   when   isnull(@username,'')=''   then   ''
  else   '"   /U"   end   
  +'"   /P"'+isnull(@password,'')   
  +'"   /i"   
  exec   master..xp_cmdshell   @sql   
  end   
  else   
  begin   
  --为数据导入准备临时表   
  set   @sql='select   top   0      into   '   
     from   '      
  exec(@sql)   
    
  --将数据导入到临时表   
  set   @sql='bcp   ""   in   "   
  +'"   /S"   
  +case   when   isnull(@username,'')=''   then   ''
  else   '"   /U"   end   
  +'"   /P"'+isnull(@password,'')   
  +'"   /i"   
  exec   master..xp_cmdshell   @sql   
    
  --将数据导入到正式表中   
  set   @sql='update      
  +'   set      
  +'   from      a,'   
     b'   
  +case   isnull(@tj,'')   when   ''   then   ''   
  else   '   where      end   
  exec(@sql)   
    
  --删除数据处理临时表   
  set   @sql='drop   table      
  end   
    
  --删除数据处理应答文件   
  set   @sql='del      
  exec   master..xp_cmdshell   @sql
GO
SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO
  </ccid_code></pre> 
   </td>
  </tr>
</table>
</ccid_nobr></CENTER> 
这个存储过程,基本原理其实和上面的是一样的。我先测试导出,在程序中运行后,不断刷新保存导出图片的文件夹,发现系统确实产生了数据,以文件+tmp的命名方式存放,但不知道为什么,系统运行完毕,所有的图片还是没有。这条路看来不通。
帖子发出来以后,很快有人回复。但是回复的答案就是我找到的两个存储过程的。看来问题可能无法解决。
但是任务还是的完成,最后万般无奈之下,我给认识的一位大侠发了求救信,他只是提供了一条思路,用流的方式写入。我按照这个思路,抱着试试看的心情,将代码改成如下的样式:
   set rs2=Server.CreateObject("Adodb.Recordset")
   sql2="select top 1 * from [User] order by UserID desc"
   rs2.open sql2,cn,1,3
   rs2("Photo").AppendChunk rs("Picture1")
   rs2.update
   rs2.close
   set rs2=nothing