最近在写一个升级程序,其中要求将一个旧数据库里面的所有的照片都转到新数据库。暂且把旧数据库叫OldDB,新数据库叫NewDB,新数据库里面的字段为【Photo】,旧数据库叫【Picture】 。开始我是这样做的,先读出旧数据库里的数据,然后用insert into插入:
insert
into
[
table1
]
values
("
&
rs("Picture")
&
")
后来发现不行,我以为数据类型搞错了,改了下代码,如下:
insert
into
[
table1
]
values
(‘"
&
rs("Picture")
&
"’)
多加了一对单引号,系统还是提示错误。我没有办法了,立即到优快云上找到了两条存储过程。
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

这是调用textcopy将图片数据导入和导出的语句,我原打算新旧数据库调用同一个存储过程,旧数据库先将数据导出到硬盘,新数据库在导入。在测试以后,发现不成功,页面显示不出数据,单独用textcopy测试还是可以导出数据的,但在程序中调用,没有成功。我接下来换成下面的存储过程:
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
'
+
@m_tbname
+
'
from(
select null as 类型
union all select 0 as 前缀
union all select
'
+
@fsize
+
'
as 长度
union all select null as 结束
union all select null as 格式
) a
'
exec
(
@sql
)
select
@fname_in
=
@fname
+
'
_temp
'
,
@sql
=
'
bcp "
'
+
@m_tbname
+
'
" out "
'
+
@fname_in
+
'
" /S"
'
+
@servename
+
case
when
isnull
(
@username
,
''
)
=
''
then
''
else
'
" /U"
'
+
@username
end
+
'
" /P"
'
+
isnull
(
@password
,
''
)
+
'
" /c
'
exec
master..xp_cmdshell
@sql
--
删除临时表
set
@sql
=
'
drop table
'
+
@m_tbname
exec
(
@sql
)
if
@isout
=
1
begin
set
@sql
=
'
bcp "select top 1
'
+
@fdname
+
'
from
'
+
@tbname
+
case
isnull
(
@tj
,
''
)
when
''
then
''
else
'
where
'
+
@tj
end
+
'
" queryout "
'
+
@fname
+
'
" /S"
'
+
@servename
+
case
when
isnull
(
@username
,
''
)
=
''
then
''
else
'
" /U"
'
+
@username
end
+
'
" /P"
'
+
isnull
(
@password
,
''
)
+
'
" /i"
'
+
@fname_in
+
'
"
'
exec
master..xp_cmdshell
@sql
end
else
begin
--
为数据导入准备临时表
set
@sql
=
'
select top 0
'
+
@fdname
+
'
into
'
+
@m_tbname
+
'
from
'
+
@tbname
exec
(
@sql
)
--
将数据导入到临时表
set
@sql
=
'
bcp "
'
+
@m_tbname
+
'
" in "
'
+
@fname
+
'
" /S"
'
+
@servename
+
case
when
isnull
(
@username
,
''
)
=
''
then
''
else
'
" /U"
'
+
@username
end
+
'
" /P"
'
+
isnull
(
@password
,
''
)
+
'
" /i"
'
+
@fname_in
+
'
"
'
exec
master..xp_cmdshell
@sql
--
将数据导入到正式表中
set
@sql
=
'
update
'
+
@tbname
+
'
set
'
+
@fdname
+
'
=b.
'
+
@fdname
+
'
from
'
+
@tbname
+
'
a,
'
+
@m_tbname
+
'
b
'
+
case
isnull
(
@tj
,
''
)
when
''
then
''
else
'
where
'
+
@tj
end
exec
(
@sql
)
--
删除数据处理临时表
set
@sql
=
'
drop table
'
+
@m_tbname
end
--
删除数据处理应答文件
set
@sql
=
'
del
'
+
@fname_in
exec
master..xp_cmdshell
@sql
GO
SET
QUOTED_IDENTIFIER
OFF
GO
SET
ANSI_NULLS
ON
GO

这个存储过程,基本原理其实和上面的是一样的。我先测试导出,在程序中运行后,不断刷新保存导出图片的文件夹,发现系统确实产生了数据,以文件+tmp的命名方式存放,但不知道为什么,系统运行完毕,所有的图片还是没有。这条路看来不通。
没折了,到优快云发帖子吧,地址:http://community.youkuaiyun.com/Expert/topic/5618/5618139.xml?temp=.6252252
帖子发出来以后,很快有人回复。但是回复的答案就是我找到的两个存储过程的。看来问题可能无法解决。
但是任务还是的完成,最后万般无奈之下,我给认识的一位大侠发了求救信,他只是提供了一条思路,用流的方式写入。我按照这个思路,抱着试试看的心情,将代码改成如下的样式:
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
本文记录了一个实际案例,通过多种方法尝试将旧数据库中的图片数据迁移到新数据库的过程。包括使用SQL语句直接迁移、调用存储过程进行数据导出与导入,最终采用流的方式实现了图片数据的成功迁移。
1052

被折叠的 条评论
为什么被折叠?



