今天与我师傅讨论图像保存问题时,又发现一个好东西。
图像保存的模式,我经历过两种方法:一种是保存到数据库中,它的好处是开发起来简单,只要两个读写IMAGE字段的函数就可以搞定,服务器不必另外再开服务,数据存在哪里我也不管,文件名是什么也不必操心,存在的问题是数据库变大得很快,如果是每天都要备份,那一定是个噩梦,还有读写的时间相对会长一些,因为为了在客户端显示,必须在客户端建立临时文件。
另一种是放到共享目录中,它的好处也是开发起来简单,文件上传与读取显示的函数比前面的还要短得多。存在的问题好像更多,服务器开放文件共享端口,文件存放要对应好来,既然能让用户上传,则目录还要允许读写,如果用户高兴起来,把目录中的全部文件删光光,我们哭都来不及。我曾经想出一种方法,用两个连接来处理,一个目录共享两次,一次用于文件读取,它是只读共享,另一个用于文件上传,设为某个帐户可完全访问,隐藏,程序中用该帐户上传文件。但由于配置不容易,稳定性差,天生就有安全隐患,所以也失败。
今天找到一个平衡点,就是显示图像用只读共享目录,而上传文件使用BCP功能。
以前没有用过BCP,今天试了一下,问题还挺多的,先试一段代码:
create table ##tb(aa varchar(1000))
insert into ##tb
select '<html>'
union all select '<head>'
union all select '<title>测试</title>'
union all select '</head>'
union all select '<body>'
union all select '你好,测试中'
union all select '</body>'
union all select '</html>'
--生成test.htm文件
exec master..xp_cmdshell 'bcp ##tb out c:\test.htm /P"" /c'
--删除临时表
drop table ##tb
测试成功,确实在服务器端生成了一个文件。那我们再扩展开来:
如果要导出的不是一整个表,而是某一些或一条记录,可以使用queryout
exec master..xp_cmdshell 'bcp "select RR from KSMIS.dbo.T10WJM where BH=''00050''" queryout C:\1.JPG -T -f C:\D1.fmt'
queryout后面跟要导出的文件名。
-T是指采用信任连接。
-f是指要使用指定文件的格式导出。要做文件格式还挺麻烦的,在没做文件格式之前,可以将-f C:\D1.fmt用-n来代替,但导出的结果却是前面多了四个字节,图片不像图片。
如果不带参数地运行BCP,则会列出所有的参数。
exec master..xp_cmdshell 'bcp'或在服务器命令提示符下直接输入BCP
用法: bcp {dbtable | query} {in | out | queryout | format} datafile
[-m maxerrors] [-f formatfile] [-e errfile]
[-F firstrow] [-L lastrow] [-b batchsize]
[-n native type] [-c character type] [-w wide character type]
[-N keep non-text native] [-V file format version] [-q quoted identifier]
[-C code page specifier] [-t field terminator] [-r row terminator]
[-i inputfile] [-o outfile] [-a packetsize]
[-S server name] [-U username] [-P password]
[-T trusted connection] [-v version] [-R regional enable]
[-k keep null values] [-E keep identity values]
[-h "load hints"]
格式文件可以先由BCP生成,然后加以修改,最后应用于实际字段的导出。根据以上命令行后,写出这样的SQL语句来导出:
exec master..xp_cmdshell 'bcp BSMIS.dbo.T10WJM format nul -T -n -f C:\D.fmt'
导出的文件是文本文件,类似以下内容:
8.0
1
1 SQLIMAGE 0 0 "" 1 RR ""
第一行是SQL的版本,第二行说明字段的个数,第三行是每个字段的说明,最原始导出来的是好多字段,我把其它的给删除了。并且IMAGE字段的第三个参数是4:
1 SQLIMAGE 4 0 "" 1 RR ""
我估计是导致前面会多四个字节的原因,把它改为0就正常了。