--字段用image类型/*--利用 textcopy.exe文件实现在数据库中存储/读取文件 需要textcopy.exe文件,该文件可以在sql 7.0安装光盘找到--转贴自大力--*/--建立存取处理的存储过程
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]
GOCREATE 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) --I 为存储到数据库,O 从数据库中读出成文件
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--调用示例:
--1.创建示例表和初始化数据
create table tb(id int,img image)
insert tb 
select 1,0x
union all select 2,0x
go--2.将文件保存到数据库中
declare @srv varchar(255),@db sysname,@tb sysname,@col sysname
select @srv=@@servername --服务器名
,@db=db_name() --数据库名
,@tb='tb' --表名
,@col='img' --列名
sp_textcopy @srv,'sa','sa的密码',@db,@tb,@col,'c:\test.jpg','where id=1','I' --保存到id=1的记录中,注意条件是:id=1
sp_textcopy @srv,'sa','sa的密码',@db,@tb,@col,'c:\test.doc','where id=2','I' --保存到id=2的记录中,注意条件是:id=2--3.从数据库中读出保存为文件
sp_textcopy @srv,'sa','sa的密码',@db,@tb,@col,'c:\test.jpg','where id=1','O' --读出id=1的记录,注意条件是:id=1
sp_textcopy @srv,'sa','sa的密码',@db,@tb,@col,'c:\test.doc','where id=2','O' --读出id=2的记录,注意条件是:id=2--删除测试环境
drop table tb
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]

解决方案 »

  1.   

    '如果是程序中的话,可以用ado.stream对象,不会C#,给VB的你参考:'VB/VBA中实现数据库中的文件存取'*************************************************************************
    '**
    '** 使用 ADODB.Stream 保存/读取文件到数据库
    '** 引用 Microsoft ActiveX Data Objects 2.5 Library 及以上版本
    '**
    '** ----- 数据库连接字符串模板 ---------------------------------------
    '** ACCESS数据库
    '** iConcStr = "Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False" & _
    '**     ";Data Source=数据库名"
    '**
    '** SQL数据库
    '** iConcStr = "Provider=SQLOLEDB.1;Persist Security Info=True;" & _
    '**     "User ID=用户名;Password=密码;Initial Catalog=数据库名;Data Source=SQL服务器名"
    '**
    '*************************************************************************
    '
    '保存文件到数据库中
    Sub s_SaveFile()
        Dim iStm As ADODB.Stream
        Dim iRe As ADODB.Recordset
        Dim iConcStr As String
        
        '数据库连接字符串
        iConcStr = "Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False" & _
            ";Data Source=F:\My Documents\客户资料1.mdb"
        
        '读取文件到内容
        Set iStm = New ADODB.Stream
        With iStm
            .Type = adTypeBinary    '二进制模式
            .Open
            .LoadFromFile "c:\test.doc"
        End With
        
        '打开保存文件的表
        Set iRe = New ADODB.Recordset
        With iRe
            .Open "表", iConc, adOpenKeyset, adLockOptimistic
            .AddNew         '新增一条记录
            .Fields("保存文件内容的字段") = iStm.Read
            .Update
        End With
        
        '完成后关闭对象
        iRe.Close
        iStm.Close
    End Sub'从数据库中读取数据,保存成文件
    Sub s_ReadFile()
        Dim iStm As ADODB.Stream
        Dim iRe As ADODB.Recordset
        Dim iConc As String
        
        '数据库连接字符串
        iConc = "Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False" & _
            ";Data Source=\\xz\c$\Inetpub\zj\zj\zj.mdb"
        
        '打开表
        Set iRe = New ADODB.Recordset
        iRe.Open "tb_img", iConc, adOpenKeyset, adLockReadOnly
        iRe.Filter = "id=64"    if iRe("img").ActualSize>0 Then     '保存到文件
        Set iStm = New ADODB.Stream
        With iStm
            .Mode = adModeReadWrite
            .Type = adTypeBinary
            .Open
            .Write iRe("img")
            .SaveToFile "c:\test.doc"
        End With
        
        '关闭对象
        iStm.Close
    End If    iRe.Close
    End Sub
      

  2.   

    SQL Server存储图像数据的策略与方法  
     
    2003-01-13· ·郑浩 张蔚··yesky  目前对于图像数据的管理大都采用表+实体的方法,即图像数据以文件形式存放于指定的计算机目录下,在数据库表中只反映图像数据文件的存储路径。这种管理模式,给数据的维护增加了难度,同时,也给数据的安全带来一定的隐患。因此,要真正做到各类数据在数据库中安全管理,研究和探索直接将图像数据存储在数据库关系表中的方法是非常必要的。  笔者在Visual Basic 6.0开发环境中,采用客户机/服务器的工作方式,针对SQL Server数据库关系表中存储图像数据的问题进行了初步探讨,提出了一套基本解决方案,供读者参考。  一、 存储图像数据的策略  图像数据库技术一直致力于解决海量数字图像的有效存储和管理问题。它是数据库技术的继承和发展,一方面,图像数据和文本数据存在着本质的区别,在文本数据领域得以成功应用的传统数据库技术,如果一成不变的照搬到图像数据库领域,结果往往是低效,甚至无效;另一方面,传统数据库的许多成果,如SQL语言、索引技术等都值得图像数据库借鉴。上述两个方面的结合成为目前图像数据库技术发展的主流。  1.1 BLOB数据类型  BLOB是非常巨大的不定的二进制或者字符型数据,通常是文档(.txt、.doc)和图片(.jpeg、.gif、.bmp),它可以存储在数据库中。在SQL Server中,BLOB可以是text、ntext或者image数据类型。 Image数据类型存储的是长度不确定的二进制数据,最大长度是2GB。  BLOB数据在SQL Server系统中的存储方式不同于普通的数据类型,对于普通类型的数据系统直接在用户定义的字段上存储数据值,而对于BLOB类型数据,系统开辟新的存储页面来存放这些数据,表中BLOB类型数据字段存放的仅是一个16个字节的指针,该指针指向存放该条记录的BLOB数据的页面。  1.2 BLOB的设计策略  BLOB数据是数据量很大的数据类型,它会占用大量的硬盘空间、内存和网络资源,因此合理地设计包含有BLOB数据类型的属性表,对提高存储效率、查询速度有很大的影响。一般BLOB的设计原则如下:  (1) 使用BLOB数据类型还是使用varchar或者varbinary数据类型  二进制大对象并不一定要存储为text、ntext或者image数据类型,它们也可以作为varchar或者varbinary数据类型村处在表格中。数据类型的选择要根据将要存储的BLOB的实际大小。如果数据不会超过8K,那么就使用Varchar或者varbinary数据类型。如果这些大对象的尺寸超过8K,那么就使用text、ntext或者image数据类型。  (2) 存储BLOB在数据库中或者在文件系统中  常见的设计问题是将图片存在数据库中还是存在文件系统中。在大多数情况下,最好把图片文件与其它数据一起存在数据库中。因为将影像数据文件存储在数据库中有许多优点:  易于管理 当BLOB与其他数据一起存储在数据库中时,BLOB和表格是数据一起备份和恢复。这样就降低了表格数据与BLOB数据不同步的机会,而且降低了其他用户无意中删除了文件系统中BLOB数据位置的路径和风险。另外,将数据存储在数据库中BLOB和其他数据的插入、更新和删除都在同一个事务中实现。这样就确保了数据的一致性和文件与数据库之间的一致性。还有一点好处是不需要为文件系统中的文件单独设置安全性。  可伸缩性 尽管文件系统被设计为能够处理大量不同大小的对象,但是文件系统不能对大量小文件进行优化。在这种情况下,数据库系统可以进行优化。  可用性 数据库具有比文件系统更多的可用性。数据库复制允许在分布式环境中复制、分配和潜在的修改数据。在主系统失效的情况下,日志转移提供了保留数据库备用副本的方法。  当然,在某些情况下,将图片存储在文件系统中将是更好的选择:  (1)使用图片的应用程序需要数据流性能,例如实时的视频重现。  (2)象Microsoft PhotoDraw或者Adobe Photoshop这样的应用程序经常访问BLOB,这些应用程序只知道怎样访问文件。  (3)需要使用一些NTFS文件系统中的特殊功能,例如远程存储。
     
    二、 存储图像数据的方法  1 建立具有image宇段的SQL Server数据库  当需要在SQL Server数据库中存储图像数据时,首先应建立包含image数据类型字段的数据库关系表。SQL Server数据库平台支持的数据类型中,image数据类型主要用于存储图像数据等大段的二进制数据。SQL Server 7.0之后的版本,image类型可存储2GB的数据。   2 使用Remote Data控件建立与数据库的连接  Remote Data控件是在Visual Basic应用程序中用来获取远程数据的控件。它在.远程数据对象(RDO)和数据绑定控件之间提供了接口,只要给它提供有关数据存储的位置、获取的数据和一些接口控制,就可以连接到数据库,实现对数据库的基本操作。   使用Remote Data控件建立与远程数据库的连接步骤如下:  1.在Visual Basic的窗体中加入一个Remote Data控件。 ,  2.在Remote Data控件DataSourceName属性的下拉列表中选择一个ODBC数据源。例如pubs。  3.在Remote Data控件的SQL属性中输入SQL查询语句。例如,Select * from pub_info。  2.3 绑定OLE和Remote Data控件实现图像数据的存储与编辑  OLE是允许应用程序相互之间交换和显示数据的一项技术,使用OLE,可以从支持OLE技术的任何应用程序中读取信息,也可以在任何支持OLE的程序中显示和编辑它。在Visual Basic中,可利用OLE容器控件与Remote Data控件的绑定,来实现显示、存储和编辑SQL Serve数据库中的image类型数据。  1.显示SQL Serve数据库image类型字段的图像数据  具体步骤如下:  (1)在加入了Remote Data控件的Visual Basic的窗体中,添加一个OLE容器控件。创建OLE容器控件时,会出现“插入对象’:对话框,此时点击“取消”按钮,不必为该容器指定对象。  (2)将OLE容器控件的DataSource属性设置为Remote Data控件的名字,实现控件的绑定。  (3)在OLE容器控件。DataField属性的下拉列表中选择要显示的字段名。例如,logo。  (4)运行应用程序。对于包含image数据类型的logo字段的数据将在OLE容器控件中显示一幅图像。  2.在SQL Sever数据库image类型字段中添加存储图像数据  具体步骤如下:  (1)将Remote Data控件的EOFAction属性设置为rdAddNew,实现数据库的数据添加功能。  (2)在Visual Baisic的窗体中添加一个CommandButton控件,并编写图像文件嵌入OLE容器控件的程序代码。例如:Private Sub Command_Click()OLEl.CreateEmbed“c:\图片.bmp”End Sub   (3)运行应用程序,点击Remote Data控件的记录指示按钮,移动到新的记录,然后点击CommandButton控件按钮,实现图像数据的添加入库操作。  3.编辑SQL Serve数据库image数据类型字段的图像数据  具体步骤如下:  (1)在Visual Basic的窗体中添加一个CommandButton控件,编写对OLE对象的编辑程序代码。例如:Private Sub Command2--_Click()OLEl.DoVerb VbOLEOpenEnd Sub    (2)运行应用程序,点击Remote Data控件的记录指示按钮,选择需要编辑的图像,然后点击CommandButton控件按钮,在分隔的应用程序窗口打开对象,进行图像的编辑操作。  4、图像文件自动入库方式的实现  在数据库的实际应用中,经常需要将图像文件批量存储,以提高数据入库操作的自动化程度。对于图像文件批量存储,在程序代码的编写中,可充分利用OLE容器控件与RemoteData控件的诸多属性和方法,加以实现。  具体步骤如下:  (1)将OLE和RemoteData控件的Visible属性设置成False,使OLE和RemoteData控件不可视。  (2)建立图像文件的批处理文件。  (3)编写以下基本代码,实现批处理功能。Private Sub Command3_Click()Dim FileName As StringOpen "c:\tesffile.txt"ForlnputAs#1'打开批处理文件。DoWhileNotEOF(1)'循环至文件尾。Input#l,FileName'读入图像文件名。MSRDCl.Resultset.AddNew‘结果集添加记录OLEl.CreateEmbedFileName‘嵌入图像文件MSRDCl.Resultset.UpdateLoopClose #1End Sub   (4)运行应用程序。点击CommandButton控件按钮,完成图像文件的自动入库。  五、结束语  随着SQL Serve数据库管理系统功能的不断增强、性能的不断完善,将各类数据完全由数据库管理系统统一存储和管理,已成为技术发展的趋势。只有这样,SQL Serve数据库管理系统的强大功能才能得到充分发挥,数据的安全性才能得到充分的保障,使得诸如数据库复制、数据的转移等许多工作,变得非常简单容易。
      

  3.   

    我按照 zjcxc(邹建) 的方法做,但是出现“ 'textcopy' 不是内部或外部命令,也不是可运行的程序”的提示
    这是怎么回事呢
      

  4.   

    需要textcopy.exe文件,该文件可以在sql 7.0安装光盘找到
    将textcopy.exe文件复制到windows系统目录下就可以了.
      

  5.   

    --或者用bcpif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_binaryIO]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[p_binaryIO]
    GO/*--bcp 实现二进制文件的导入导出 支持image,text,ntext字段的导入/导出
    image适合于二进制文件,包括:Word文档,Excel文档,图片,音乐等
    text,ntext适合于文本数据文件 注意:导入不会新增记录,所以导入前要对表进行初始化,即插入记录
    导入时,将覆盖满足条件的所有行
    导出时,将把所有满足条件的行导出到指定文件中
    此存储过程仅用bcp实现
    --邹建 2003.08---*//*--调用示例
    --数据导出
    exec p_binaryIO 'zj','','','acc_演示数据..tb','img','c:\zj1.dat'--数据导入
    exec p_binaryIO 'zj','','','acc_演示数据..tb','img','c:\zj1.dat','',0
    --*/
    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
    endend--生成数据处理应答文件
    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 @sqlgo
      

  6.   

    textcopy.exe文件在安装后的文件夹里有
    拷贝到windows系统目录下也就是windows目录下吧
      

  7.   

    你只要保证在任意目录下,输入textcopy都可以被执行,就成功了.