在 C#中实现存储图片到 SQLServer2005 中实现存储图片到 在论坛中碰到有朋友问到如和把图片存到数据库中,自己用 VS2005+SQLServer2005 实现了这个功能. 上面是主界面 上面是显示界面 数据库为 Picture,数据表为 Picture,表结构设计如下所示: PictureID int 4, nvarchar(50) 下面是主界面的代码 namespace PictureToDataBase { public partial class Main : Form { string fileSaveURL; PictureContent Image, PictureText public Main() { InitializeComponent(); } private void cmdOpen_Click(object sender, EventArgs e) { this.openFileDialog.ShowDialog(); string fileURL = this.openFileDialog.FileName; this.picView.ImageLocation = fileURL; this.fileSaveURL = fileURL; } private void cmdSave_Click(object sender, EventArgs e) { //获取图片的二进制流 FileStream fs = new FileStream(fileSaveURL, FileMode.Open); BinaryReader br = new BinaryReader(fs); byte[] photo = br.ReadBytes((int)fs.Length); br.Close(); fs.Close(); //把图片写到数据库中 string conn = @"Data Source=JNITDEV\SQLEXPRESS;Initial Catalog=Picture;Integrated Security=True"; using (SqlConnection sqlConn = new SqlConnection(conn)) { SqlCommand sqlComm = new SqlCommand(); sqlConn.Open(); sqlComm.Connection = sqlConn; sqlComm.CommandText = "INSERT INTO Picture (PictureContent, PictureText) VALUES (@Picture,'Test')"; sqlComm.CommandType = CommandType.Text; sqlComm.Parameters.Add("@Picture", SqlDbType.Image, photo.Length).Value = photo; sqlComm.ExecuteNonQuery(); } } private void cmdShow_Click(object sender, EventArgs e) { PicShow picShow = new PicShow(); picShow.Show(); } } } 下面是显示界面代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; using System.Data.SqlClient; namespace PictureToDataBase { public partial class PicShow : Form { int picID; int maxID; int minID; string conn = @"Data Source=JNITDEV\SQLEXPRESS;Initial Catalog=Picture;Integrated Security=True"; public PicShow() { InitializeComponent(); } private void PicShow_Load(object sender, EventArgs e) { using (SqlConnection sqlConn = new SqlConnection(conn)) { SqlCommand sqlComm = new SqlCommand(); sqlConn.Open(); sqlComm.Connection = sqlConn; sqlComm.CommandText = "SELECT TOP 1 PictureContent,PictureID FROM Picture ORDER BY PictureID DESC"; sqlComm.CommandType = CommandType.Text; using (SqlDataReader dr = sqlComm.ExecuteReader()) { dr.Read(); MemoryStream MemoryStream((byte[])dr[0]); ms = new Image img = Image.FromStream(ms); this.picShowPic.Image = img; this.picID = (int)dr[1]; } SetButton(); } } private void SetButton() { using (SqlConnection sqlConn = new SqlConnection(conn)) { SqlCommand sqlComm = new SqlCommand(); sqlConn.Open(); sqlComm.Connection = sqlConn; sqlComm.CommandText = "SELECT MAX(PictureID) AS maxID,MIN(PictureID) AS minID FROM Picture"; sqlComm.CommandType = CommandType.Text; using (SqlDataReader dr = sqlComm.ExecuteReader()) { dr.Read(); maxID = (int)dr[0]; minID = (int)dr[1]; } } this.cmdPreview.Enabled = picID > minID; this.cmdNext.Enabled = picID < maxID; } private void cmdNext_Click(object sender, EventArgs e) { this.picID++; LoadPicture(); SetButton(); } private void LoadPicture() { using (SqlConnection sqlConn = new SqlConnection(conn)) { SqlCommand sqlComm = new SqlCommand(); sqlConn.Open(); sqlComm.Connection = sqlConn; sqlComm.CommandText = "SELECT PictureContent,PictureID FROM Picture WHERE PictureID = @picID"; sqlComm.CommandType = CommandType.Text; sqlComm.Parameters.Add("@picID", SqlDbType.Int).Value = picID; using (SqlDataReader dr = sqlComm.ExecuteReader()) { dr.Read();//以下把数据库中读出的 Image 流在图片框 中显示出来. MemoryStream MemoryStream((byte[])dr[0]); Image img = Image.FromStream(ms); ms = new this.picShowPic.Image = img; this.picID = (int)dr[1]; } } } private void cmdPreview_Click(object sender, EventArgs e) { this.picID--; LoadPicture(); SetButton(); } } } 编程实现 SqlServer 扩展存储过程并实现 Image 类型参数的输入和结果的返回 SQLServer 有一项即将要过时的功能,那就是扩展存储过程(在 MSDN 上查询该方面的资料的时候,上面都有一个提示 说是这个功能将会在以后的 SQL 版本中删除,建议使用 CLR 集成) 。虽然要过时了,但是看着现在有不少的 DB 还在用 SQL2000说明这个功能至少还有几年有效期。对了,忘了说了扩展存储过程是干啥用的,懒得查最官方的说法了,用我的 语言来说,那就是使用自己的开发语言,来实现一些数据库没有实现的功能,比如说我想在数据库里面直接作 MD5的加密 和解密,这个功能 SQL Server 本来不具有的,但是可以自己写一个扩展存储过程来实现。 开发扩展存储过程的开发语言还是有些要求的,就是要能实现导出函数的,如 C(VC,BCB,其它的 C),Delphi 等,C#由 于无法实现导出函数,所以就不能开发了,不过他可以开发 CLR 集成。由于我只会 Delphi,所以我就用它来作例子。 扩展存储过程的 hellowolrd(铁匠出品) (铁匠出品) 如果仅仅写一个 hello wolrd,Delphi 是不需要任何东西就可以实现,那就是:新建一个 DLL 的工程,在里面写个如下函 数: function xp_helloWorld: Boolean; stdcall; begin //在这里面可以写一个文件好看到效果,具体的代码我就不写了 end; 然后把它放在导出函数里面: exports xp_helloWorld; 再在 SQLSERVER 里去注册,注意注册扩展存储过程只能在 Master 库里实现,还要求操作者有一定的权限,SQL 如下: if exists (select * from master.dbo.sysobjects where id = object_id('xp_helloWorld')) execute sp_dropextendedproc 'xp_helloWorld' go --我编写的 dll 在'D:\PersonWork\SQLExtProcedure\目录下面,修改成你的编写的目录 execute sp_addextendedproc 'xp_helloWorld', 'D:\PersonWork\SQLExtProcedure\sqlExtProcedure.dll' go 然后在写 SQL exec Master.dbo.xp_helloWorld 就能看到效果了。 实用的扩展存储过程(铁匠出品) 实用的扩展存储过程(铁匠出品) 但是我们开发东西不是一个 helloworld 就能够用的,所以我们就得引入新的东西:MsOdsApi,这个是一个我们的代码去 调用 sql 现有功能的入口,因为 Sqlserver 的 SDK 并没有给 Delphi 作个版本,所以我们只好自己辛苦一下来转换他们的 头文件,不过还好网上的很多前辈们已经帮我们完成了这个工作,在本文的结束时会附上该文件。我觉得会最常用的几个函 数如下(具体的参数可以看定义,上面应该写得比较清楚了) : srv_rpcparams:获取参数的个数 srv_paraminfo:获取指定参数的信息,数据的长度,类型,数据等 srv_paramdata:获取 image 一类的值的指针 srv_describe:创造返回值的描述 srv_setcoldata:给返回的字段赋值 srv_sendrow:返回一行数据 srv_senddone:表示返回已经完成了。 于是我们开始构建新的扩展存储过程: function xp_Test(pSrvProc: SRV_PROC): Boolean; stdcall;// 这 个 传 时 来 的 参 数 pSrvProc 就 是 相 当 于 是 和 sqlserver 交互的上下文的指针了 var PType : Byte; cbMaxLen , ParaLen : DWORD; IsNULL : BOOL; fs: TFileStream; p: Pointer; n: integer; begin n := srv_rpcparams(pSrvProc);//先取一下有几个参数 srv_paraminfo(pSrvProc, 1, @PType, @cbMaxLen, @ParaLen, nil, @IsNULL);//取第一个参数的定义,注意 参数的下标是从1开始的,而不是习惯上的0 p := srv_paramdata(pSrvProc, 1);//由于我们要取 image 类型的, 所以得用这个取数据的指针, 否则就用下面这个, 注意在这之前,p 要先开好内存 //srv_paraminfo(pSrvProc, 1, @PType, @cbMaxLen, @ParaLen, @p, @IsNULL); fs := TFileStream.Create('d:\test.jpg', fmCreate);//由于无法 debug 只好能过文件把一些中间变量写到文件里, 再用 winhex 来看了 try fs.Write(n, SizeOf(Integer)); fs.Write(cbMaxLen, SizeOf(DWORD)); fs.Write(ParaLen, SizeOf(DWORD)); fs.Write(p^, ParaLen) finally FreeAndNil(fs); end; //下面开始返回一行数据 n := ParaLen; srv_describe(pSrvProc, 1 , 'Data', SRV_NULLTERM, SRV_TDS_IMAGE, n, SRVBIGVARCHAR, n, NIL); srv_setcoldata(pSrvProc, 1 , p); srv_sendrow(pSrvProc); srv_senddone(pSrvProc, (SRV_DONE_COUNT or SRV_DONE_MORE), 0, 1); end; 还是按 hellowolrd 的方法把它注册到 SQLServer 里面去。不过由于 Image 类型的字段不能在存储过程里设置临时变量, 所以我们还有再麻烦一下: Create PROCEDURE [dbo].[UXP_Test] @in1 Image AS BEGIN Insert into Test1(Data) exec Master.dbo.xp_Test @in1 END GO 这样来把我们处理过后的 Image 类型的字段插入到 DB 里面去。 最后来看看那个 Test.jpg 的内容: Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 00000000 00000010 00000020 00000030 01 00 00 00 10 00 00 00 72 03 00 00 47 49 46 38 39 61 A0 00 58 00 A2 00 00 63 9C 9C FF 63 00 00 9C 00 00 63 FF CE 31 31 FE 01 02 00 00 00 00 00 00 21 FF 0B 4E 45 54 53 43 41 50 45 32 2E 30 03 ........r...GIF8 9a?X.?.c 湝?c.. ?.c??1?...... .!?.NETSCAPE2.0. 点它一下看大图,就可以看到前四位是1,也就是传入了1个参数,接下来4位值是16(从这里也可以看出来那些 image 类 型 的定义果真是16位这么长) ,再接下来4位这才是数据的真正长度,我是插入了一个 GIF 动画,所以它的长度和文件的 长度是一样的:882,再后面就是文件的开始了 GIF89a 一个标准的 GIF 文件头 看看这些数据插入到 DB 里是不是正确的呢?来看下图: 0x 开头,说明它是以16进制数显示的,看开头的几位:474946383961和上面的16进制数对比一下可以看到,这里面的 数据是正确的,也就是说我们的 Image 传入处理后,再返回来这一切都是成功的。 最后贴一下:MsOdsApi.pas(从下一行开始复制) unit MsOdsApi; //-----------------------------------------------------------// Open Data Services header file: srv.h // Copyright (c) 1989, 1990, 1991, 1997 by Microsoft Corp. // // Avoid double inclusion //#ifndef _ODS_SRV_H_ // _ODS_SRV_H_ //#include "windows.h" // ODS uses pack(4) on all CPU types //#pragma pack(4) //#ifdef __cplusplus //extern "C" { //#endif // define model //#if !defined( FAR ) // FAR far //#endif //-----------------------------------------------------------// Formats of data types //#if !defined(DBTYPEDEFS) // Do not conflict with DBLIB definitions //#if !defined(MAXNUMERICLEN) // Do not conflict with ODBC definitions // DBTYPEDEFS interface uses Windows; type DBBOOL DBBYTE DBTINYINT DBSMALLINT = Byte; = Byte; = Byte; = Smallint; DBUSMALLINT = Word; DBINT DBCHAR PDBCHAR DBBINARY DBBIT DBFLT8 = Longint; = Char; = ^DBCHAR; = Byte; = Byte; = Double; srv_datetime = record // Format for SRVDATETIME dtdays: Longint; // number of days since 1/1/1900 dttime: Longword; // number 300th second since mid end; DBDATETIME = srv_datetime; srv_dbdatetime4 = record // Format for SRVDATETIM4 numdays: Word; // number of days since 1/1/1900 nummins: Word; // number of minutes sicne midnight end; DBDATETIM4 = srv_dbdatetime4; srv_money = record // Format for SRVMONEY mnyhigh: Longint; mnylow : Longword; end; DBMONEY = srv_money; DBFLT4 = Double; DBMONEY4 = Longint; const MAXNUMERICDIG = 38; DEFAULTPRECISION = 19; // 18 DEFAULTSCALE MAXNUMERICLEN = 0; = 16; type srv_dbnumeric = packed record // Format for SRVNUMERIC,SRVNUMERICN,SRVDECIMAL,SRVDECIMALN precision: Byte; scale sign val end; DBNUMERIC = srv_dbnumeric; DBDECIMAL = DBNUMERIC; : Byte; : Byte; // 1 = Positive, 0 = Negative : array [0..MAXNUMERICLEN-1] of Byte; // Padded little-endian value //#endif // #if !defined(MAXNUMERICLEN) //#endif // #if !defined( DBTYPEDEFS ) //-----------------------------------------------------------// Constants used by APIs // Type Tokens const SRV_TDS_NULL SRV_TDS_TEXT = $1f; = $23; SRV_TDS_GUID SRV_TDS_VARBINARY SRV_TDS_INTN SRV_TDS_VARCHAR SRV_TDS_BINARY SRV_TDS_IMAGE SRV_TDS_CHAR SRV_TDS_INT1 SRV_TDS_BIT SRV_TDS_INT2 SRV_TDS_DECIMAL SRV_TDS_INT4 SRV_TDS_DATETIM4 SRV_TDS_FLT4 SRV_TDS_MONEY SRV_TDS_DATETIME SRV_TDS_FLT8 SRV_TDS_NUMERIC SRV_TDS_NTEXT SRV_TDS_BITN SRV_TDS_DECIMALN SRV_TDS_NUMERICN SRV_TDS_FLTN SRV_TDS_MONEYN SRV_TDS_DATETIMN SRV_TDS_MONEY4 SRV_TDS_INT8 SRV_TDS_BIGVARBINARY SRV_TDS_BIGVARCHAR SRV_TDS_BIGBINARY SRV_TDS_BIGCHAR = $24; = $25; = $26; = $27; = $2d; = $22; = $2f; = $30; = $32; = $34; = $37; = $38; = $3a; = $3b; = $3c; = $3d; = $3e; = $3f; = $63; = $68; = $6a; = $6c; = $6d; = $6e; = $6f; = $7a; = $7f; // SQL 2000 and later = $A5; = $A7; = $AD; = $AF; SRV_TDS_NVARCHAR SRV_TDS_NCHAR = $e7; = $ef; // Datatypes // Also: values of symbol parameter to srv_symbol when type = SRV_DATATYPE SRVNULL SRVTEXT SRVGUID SRVVARBINARY SRVINTN SRVVARCHAR SRVBINARY SRVIMAGE SRVCHAR SRVINT1 SRVBIT SRVINT2 SRVDECIMAL SRVINT4 SRVDATETIM4 SRVFLT4 SRVMONEY SRVDATETIME SRVFLT8 SRVNUMERIC SRVNTEXT SRVBITN = SRV_TDS_NULL; = SRV_TDS_TEXT; = SRV_TDS_GUID; = SRV_TDS_VARBINARY; = SRV_TDS_INTN; = SRV_TDS_VARCHAR; = SRV_TDS_BINARY; = SRV_TDS_IMAGE; = SRV_TDS_CHAR; = SRV_TDS_INT1; = SRV_TDS_BIT; = SRV_TDS_INT2; = SRV_TDS_DECIMAL; = SRV_TDS_INT4; = SRV_TDS_DATETIM4; = SRV_TDS_FLT4; = SRV_TDS_MONEY; = SRV_TDS_DATETIME; = SRV_TDS_FLT8; = SRV_TDS_NUMERIC; = SRV_TDS_NTEXT; = SRV_TDS_BITN; = SRV_TDS_DECIMALN; = SRV_TDS_NUMERICN; = SRV_TDS_FLTN; = SRV_TDS_MONEYN; SRVDECIMALN SRVNUMERICN SRVFLTN SRVMONEYN SRVDATETIMN SRVMONEY4 SRVINT8 = SRV_TDS_DATETIMN; = SRV_TDS_MONEY4; = SRV_TDS_INT8; // SQL 2000 and later SRVBIGVARBINARY = SRV_TDS_BIGVARBINARY; SRVBIGVARCHAR = SRV_TDS_BIGVARCHAR; SRVBIGBINARY SRVBIGCHAR SRVNVARCHAR SRVNCHAR = SRV_TDS_BIGBINARY; = SRV_TDS_BIGCHAR; = SRV_TDS_NVARCHAR; = SRV_TDS_NCHAR; // values for srv_symbol type parameter SRV_ERROR SRV_DONE = 0; = 1; SRV_DATATYPE = 2; SRV_EVENT = 4; // values for srv_symbol symbol parameter, when type = SRV_ERROR SRV_ENO_OS_ERR SRV_INFO = 0; = 1; SRV_FATAL_PROCESS = 10; SRV_FATAL_SERVER = 19; // Types of server events // Also: values for srv_symbol symbol parameter, when type = SRV_EVENT SRV_CONTINUE SRV_LANGUAGE SRV_CONNECT SRV_RPC SRV_RESTART SRV_DISCONNECT SRV_ATTENTION SRV_SLEEP SRV_START = 0; = 1; = 2; = 3; = 4; = 5; = 6; = 7; = 8; SRV_STOP SRV_EXIT SRV_CANCEL SRV_SETUP SRV_CLOSE SRV_PRACK SRV_PRERROR = 9; = 10; = 11; = 12; = 13; = 14; = 15; SRV_ATTENTION_ACK = 16; SRV_CONNECT_V7 SRV_SKIP SRV_TRANSMGR SRV_OLEDB = 17; = 18; = 20; = 99; = 100; = 16; // TDS type for TDS 7 clients. Overloaded with SRV_ATTENTION_ACK SRV_INTERNAL_HANDLER SRV_PROGRAMMER_DEFINED // values for srv_config option parameter SRV_CONNECTIONS SRV_LOGFILE SRV_STACKSIZE SRV_REMOTE_ACCESS = 1; = 2; = 3; = 7; SRV_REMOTE_CONNECTIONS = 9; SRV_MAX_PACKETS = 10; SRV_MAXWORKINGTHREADS = 11; SRV_MINWORKINGTHREADS = 12; SRV_THREADTIMEOUT SRV_MAX_PACKETSIZE SRV_THREADPRIORITY SRV_ANSI_CODEPAGE = 13; = 17; = 18; = 19; SRV_DEFAULT_PACKETSIZE = 26; SRV_PASSTHROUGH = 27; // vlaues for srv_config value parameter when option = SRV_THREADPRIORITY SRV_PRIORITY_LOW SRV_PRIORITY_NORMAL SRV_PRIORITY_HIGH = THREAD_PRIORITY_LOWEST; = THREAD_PRIORITY_NORMAL; = THREAD_PRIORITY_HIGHEST; SRV_PRIORITY_CRITICAL = THREAD_PRIORITY_TIME_CRITICAL; // values for srv_sfield field parameter SRV_SERVERNAME = 0; SRV_VERSION = 6; // Length to indicate string is null terminated SRV_NULLTERM = -1; // values of msgtype parameter to srv_sendmsg SRV_MSG_INFO = 1; SRV_MSG_ERROR = 2; // values of status parameter to srv_senddone // Also: values for symbol parameters to srv_symbol when type = SRV_DONE SRV_DONE_FINAL SRV_DONE_MORE SRV_DONE_ERROR SRV_DONE_COUNT = $0000; = $0001; = $0002; = $0010; = $0080; SRV_DONE_RPC_IN_BATCH // return values of srv_paramstatus SRV_PARAMRETURN SRV_PARAMDEFAULT = $0001; = $0002; // return values of srv_rpcoptions SRV_RECOMPILE SRV_NOMETADATA = $0001; = $0002; // values of field parameter to srv_pfield // SRV_LANGUAGE 1 // SRV_EVENT 4 already defined above already defined above SRV_SPID SRV_NETSPID SRV_TYPE SRV_STATUS SRV_RMTSERVER SRV_HOST SRV_USER SRV_PWD SRV_CPID SRV_APPLNAME SRV_TDS SRV_CLIB SRV_LIBVERS SRV_ROWSENT SRV_BCPFLAG SRV_NATLANG SRV_PIPEHANDLE SRV_NETWORK_MODULE SRV_NETWORK_VERSION = 10; = 11; = 12; = 13; = 14; = 15; = 16; = 17; = 18; = 19; = 20; = 21; = 22; = 23; = 24; = 25; = 26; = 27; = 28; = 29; SRV_NETWORK_CONNECTION SRV_LSECURE SRV_SAXP SRV_UNICODE_USER SRV_UNICODE_PWD SRV_SPROC_CODEPAGE = 30; = 31; = 33; = 35; = 36; // return value of SRV_TDSVERSION macro SRV_TDS_NONE = 0; SRV_TDS_2_0 SRV_TDS_3_4 SRV_TDS_4_2 = 1; = 2; = 3; SRV_TDS_6_0 SRV_TDS_7_0 = 4; = 5; // Return values from APIs type SRVRETCODE = Integer; RETCODE = Integer; // SUCCEED or FAIL const SUCCEED = 1; FAIL = 0; // Successful return value // Unsuccessful return value SRV_DUPLICATE_HANDLER = 2; // additional return value for srv_pre/post_handle //-----------------------------------------------//PreDeclare structures // {struct srv_server; typedef struct srv_server SRV_SERVER; struct srv_config; typedef struct srv_config SRV_CONFIG; struct srv_proc; typedef struct srv_proc SRV_PROC;} type SRV_SERVER = Pointer; SRV_CONFIG = Pointer; SRV_PROC = Pointer; //-----------------------------------------------//-----------------------------------------------// ODS MACROs & APIs // Describing and sending a result set function srv_describe(srvproc: SRV_PROC; colnumber: Integer; column_name: PCHAR; namelen: Integer; desttype, destlen, srctype, srclen: Integer; srcData: Pointer ): Integer; cdecl; function srv_setutype(srvproc: SRV_PROC; column: Integer; usertype: Longint): Integer; cdecl; function srv_setcoldata(srvproc: SRV_PROC; column: Integer; data: Pointer): Integer; cdecl; function srv_setcollen(srvproc: SRV_PROC; column, len: Integer): Integer; cdecl; function srv_sendrow(srvproc: SRV_PROC): Integer; cdecl; function srv_senddone(srvproc: SRV_PROC; status, curcmd: Word; count: Longint): Integer; cdecl; // Dealing with Extended Procedure parameters function srv_rpcparams(srvproc: SRV_PROC): Integer; cdecl; function srv_paraminfo(srvproc: SRV_PROC; n: Integer; pbType: PByte; pcbMaxLen, pcbActualLen: PULONG; pbData: PByte; pfNull: PBOOL): Integer; cdecl; function srv_paramsetoutput(srvproc: SRV_PROC; n: Integer; pbData: PByte; cbLen: ULONG; fNull: BOOL): Integer; cdecl; function srv_paramdata(srvproc: SRV_PROC; n: Integer): Pointer; cdecl; function srv_paramlen(srvproc: SRV_PROC; n: Integer): Integer; cdecl; function srv_parammaxlen(srvproc: SRV_PROC; n: Integer): Integer; cdecl; function srv_paramtype(srvproc: SRV_PROC; n: Integer): Integer; cdecl; function srv_paramset(srvproc: SRV_PROC; n: Integer; data: Pointer; int: Integer): Integer; cdecl; function srv_paramname(srvproc: SRV_PROC; n: Integer; var len: Integer): PChar; cdecl; function srv_paramnumber(srvproc: SRV_PROC; name: PChar; namelen: Integer): Integer; cdecl; //-------------------------------------------------------------//-------------------------------------------------------------// The rest of these APIs are still supported, in SQL Server 7.0, // but may not be supported after SQL Server 7.0 // MACROs { SRV_GETCONFIG(a) srv_getconfig (a) SRV_GETSERVER(a) SRV_GOT_ATTENTION(a) SRV_EVENTDATA(a) SRV_IODEAD(a) SRV_TDSVERSION(a) srv_getserver (a) srv_got_attention ( a ) (a) (a) ( a )} srv_eventdata srv_iodead srv_tdsversion function srv_getconfig(server: SRV_SERVER): SRV_CONFIG; cdecl; function srv_getserver(srvproc: SRV_PROC): SRV_SERVER; cdecl; function srv_got_attention(srvproc: SRV_PROC): Bool; cdecl; function srv_eventdata(srvproc: SRV_PROC): Pointer; cdecl; // Memory function srv_alloc(ulSize: Longint): Pointer; cdecl; function srv_bmove(from: Pointer; pto: Pointer; count: Longint): Integer; cdecl; function srv_bzero(location: Pointer; count: Longint): Integer; cdecl; function srv_free(ptr: Pointer): Integer; cdecl; function srv_config_fn(config: SRV_CONFIG; option: Longint; value: PChar; valuelen: Integer): Integer; cdecl; function srv_config_alloc: SRV_CONFIG; cdecl; function srv_convert(srvproc: SRV_PROC; srctype: Integer; src: Pointer; srclen: DBINT; desttype: Integer; dest: Pointer; destlen: DBINT): Integer; cdecl; { int (* srv_errhandle(int (* handler)(SRV_SERVER * server, SRV_PROC int BYTE BYTE int char int char int * srvproc, srverror, severity, state, oserrnum, * errtext, errtextlen, * oserrtext, oserrtextlen))) ( SRV_SERVER * server, SRV_PROC int BYTE BYTE int char int char int } function srv_event_fn(srvproc: SRV_PROC; event: Integer; data: PByte): Integer; cdecl; function srv_getuserdata(srvproc: SRV_PROC): Pointer; cdecl; function srv_getbindtoken(srvproc: SRV_PROC; token_buf: PChar): Integer; cdecl; function srv_getdtcxact(srvproc: SRV_PROC; ppv: Pointer): Integer; cdecl; * srvproc, srverror, severity, state, oserrnum, * errtext, errtextlen, * oserrtext, oserrtextlen ); //typedef int (* EventHandler)(void*); type EventHandler = Pointer; function srv_handle(server: SRV_SERVER; int: Longint; handler: EventHandler): EventHandler; cdecl; function srv_impersonate_client(srvproc: SRV_PROC): Integer; cdecl; function srv_init(config: SRV_CONFIG; connectname: PChar; namelen: Integer): SRV_SERVER; cdecl; function srv_iodead(srvproc: SRV_PROC): Bool; cdecl; function srv_langcpy(srvproc: SRV_PROC; start, nbytes: Longint; buffer: PChar): Longint; cdecl; function srv_langlen(srvproc: SRV_PROC): Longint; cdecl; function srv_langptr(srvproc: SRV_PROC): Pointer; cdecl; function srv_log(server: SRV_SERVER; datestamp: Bool; msg: PChar; msglen: Integer): Integer; cdecl; function srv_paramstatus(srvproc: SRV_PROC; n: Integer): Integer; cdecl; function srv_pfield(srvproc: SRV_PROC; field: Integer; len: PInteger): PChar; cdecl; function srv_returnval(srvproc: SRV_PROC; value_name: PDBCHAR; len: Integer; status: Byte; iType, maxlen, datalen: DBINT; value: PByte): Integer; cdecl; function srv_revert_to_self(srvproc: SRV_PROC): Integer; cdecl; function srv_rpcdb(srvproc: SRV_PROC; len: PInteger): PChar; cdecl; function srv_rpcname(srvproc: SRV_PROC; len: PInteger): PChar; cdecl; function srv_rpcnumber(srvproc: SRV_PROC): Integer; cdecl; function srv_rpcoptions(srvproc: SRV_PROC): Word; cdecl; function srv_rpcowner(srvproc: SRV_PROC; len: PInteger): PChar; cdecl; function srv_run(server: SRV_SERVER): Integer; cdecl; function srv_sendmsg(srvproc: SRV_PROC; msgtype: Integer; msgnum: DBINT; msgClass, state: DBTINYINT; rpcname: PChar; rpcnamelen: Integer; linenum: Word; msg: PChar; msglen: Integer): Integer; cdecl; function srv_ansi_sendmsg(srvproc: SRV_PROC; msgtype: Integer; msgnum: DBINT; msgClass, state: DBTINYINT; rpcname: PChar; rpcnamelen: Integer; linenum: Word; msg: PChar; msglen: Integer): Integer; cdecl; function srv_sendstatus(srvproc: SRV_PROC; status: Longint): Integer; cdecl; function srv_setuserdata(srvproc: SRV_PROC; ptr: Pointer): Integer; cdecl; function srv_sfield(server: SRV_SERVER; field: Integer; len: PInteger): PChar; cdecl; function srv_symbol(iType, symbol: Integer; len: PInteger): PChar; cdecl; function srv_tdsversion(srvproc: SRV_PROC): Integer; cdecl; function srv_writebuf(srvproc: SRV_PROC; ptr: Pointer; count: Word): Integer; cdecl; function srv_willconvert(srctype, desttype: Integer): Bool; cdecl; procedure srv_ackattention(srvproc: SRV_PROC); cdecl; function srv_terminatethread(srvproc: SRV_PROC): Integer; cdecl; function srv_sendstatistics(srvproc: SRV_PROC): Integer; cdecl; function srv_clearstatistics(srvproc: SRV_PROC): Integer; cdecl; function srv_setevent(server: SRV_SERVER; event: Integer): Integer; cdecl; function srv_message_handler(srvproc: SRV_PROC; errornum: Integer; severity, state: Byte; oserrnum: Integer; errtext: PChar; errtextlen: Integer; oserrtext: PChar; oserrtextlen: Integer): Integer; cdecl; function srv_pre_handle(server: SRV_SERVER; srvproc: SRV_PROC; event: Longint; handler: EventHandler; remove: Bool): Integer; cdecl; function srv_post_handle(server: SRV_SERVER; srvproc: SRV_PROC; event: Longint; handler: EventHandler; remove: Bool): Integer; cdecl; function srv_post_completion_queue(srvproc: SRV_PROC; inbuf: PChar; inbuflen: PChar): Integer; cdecl; function srv_IgnoreAnsiToOem(srvproc: SRV_PROC; bTF: BOOL): Integer; cdecl; //#ifdef __cplusplus //} //#endif //#pragma pack() const SS_MAJOR_VERSION SS_MINOR_VERSION SS_LEVEL_VERSION = 7; = 00; = 0000; SS_MINIMUM_VERSION = '7.00.00.0000'; ODS_VERSION = ((SS_MAJOR_VERSION shl 24) or (SS_MINOR_VERSION shl 16)); //#endif //_ODS_SRV_H_ ////////////////////////////////////////////////////////////////// // Suggested implementation of __GetXpVersion // //__declspec(dllexport) ULONG __GetXpVersion() // // // { return ODS_VERSION; } ////////////////////////////////////////////////////////////////// implementation const sLibName = 'Opends60.DLL'; function srv_describe; function srv_setutype; function srv_setcoldata; function srv_setcollen; function srv_sendrow; function srv_senddone; external sLibName name 'srv_describe'; external sLibName name 'srv_setutype'; external sLibName name 'srv_setcoldata'; external sLibName name 'srv_setcollen'; external sLibName name 'srv_sendrow'; external sLibName name 'srv_senddone'; // Dealing with Extended Procedure parameters function srv_rpcparams; function srv_paraminfo; function srv_paramsetoutput; external sLibName name 'srv_rpcparams'; external sLibName name 'srv_paraminfo'; external sLibName name 'srv_paramsetoutput'; function srv_paramdata; function srv_paramlen; function srv_parammaxlen; function srv_paramtype; function srv_paramset; external sLibName name 'srv_paramdata'; external sLibName name 'srv_paramlen'; external sLibName name 'srv_parammaxlen'; external sLibName name 'srv_paramtype'; external sLibName name 'srv_paramset'; function srv_paramname; function srv_paramnumber; external sLibName name 'srv_paramname'; external sLibName name 'srv_paramnumber'; //-------------------------------------------------------------// The rest of these APIs are still supported, in SQL Server 7.0, // but may not be supported after SQL Server 7.0 function srv_getconfig; function srv_getserver; function srv_got_attention; function srv_eventdata; external sLibName name 'srv_getconfig'; external sLibName name 'srv_getserver'; external sLibName name 'srv_got_attention'; external sLibName name 'srv_eventdata'; // Memory function srv_alloc; function srv_bmove; function srv_bzero; function srv_free; external sLibName name 'srv_alloc'; external sLibName name 'srv_bmove'; external sLibName name 'srv_bzero'; external sLibName name 'srv_free'; function srv_config_fn; function srv_config_alloc; function srv_convert; function srv_event_fn; function srv_getuserdata; function srv_getbindtoken; function srv_getdtcxact; function srv_handle; function srv_impersonate_client; function srv_init; function srv_iodead; function srv_langcpy; function srv_langlen; function srv_langptr; function srv_log; function srv_paramstatus; function srv_pfield; function srv_returnval; function srv_revert_to_self; external sLibName name 'srv_config'; external sLibName name 'srv_config_alloc'; external sLibName name 'srv_convert'; external sLibName name 'srv_event'; external sLibName name 'srv_getuserdata'; external sLibName name 'srv_getbindtoken'; external sLibName name 'srv_getdtcxact'; external sLibName name 'srv_handle'; external sLibName name 'srv_impersonate_client'; external sLibName name 'srv_init'; external sLibName name 'srv_iodead'; external sLibName name 'srv_langcpy'; external sLibName name 'srv_langlen'; external sLibName name 'srv_langptr'; external sLibName name 'srv_log'; external sLibName name 'srv_paramstatus'; external sLibName name 'srv_pfield'; external sLibName name 'srv_returnval'; external sLibName name 'srv_revert_to_self'; function srv_rpcdb; function srv_rpcname; function srv_rpcnumber; function srv_rpcoptions; function srv_rpcowner; external sLibName name 'srv_rpcdb'; external sLibName name 'srv_rpcname'; external sLibName name 'srv_rpcnumber'; external sLibName name 'srv_rpcoptions'; external sLibName name 'srv_rpcowner'; function srv_run; external sLibName name 'srv_run'; function srv_sendmsg; function srv_ansi_sendmsg; external sLibName name 'srv_sendmsg'; external sLibName name 'srv_ansi_sendmsg'; function srv_sendstatus; function srv_setuserdata; function srv_sfield; function srv_symbol; function srv_tdsversion; function srv_writebuf; function srv_willconvert; procedure srv_ackattention; function srv_terminatethread; function srv_sendstatistics; function srv_clearstatistics; function srv_setevent; function srv_message_handler; external sLibName name 'srv_sendstatus'; external sLibName name 'srv_setuserdata'; external sLibName name 'srv_sfield'; external sLibName name 'srv_symbol'; external sLibName name 'srv_tdsversion'; external sLibName name 'srv_writebuf'; external sLibName name 'srv_willconvert'; external sLibName name 'srv_ackattention'; external sLibName name 'srv_terminatethread'; external sLibName name 'srv_sendstatistics'; external sLibName name 'srv_clearstatistics'; external sLibName name 'srv_setevent'; external sLibName name 'srv_message_handler'; function srv_pre_handle; function srv_post_handle; function srv_post_completion_queue; function srv_IgnoreAnsiToOem; external sLibName name 'srv_pre_handle'; external sLibName name 'srv_post_handle'; external sLibName name 'srv_post_completion_queue'; external sLibName name 'srv_IgnoreAnsiToOem'; end. 2010-05-21 C#中获得 GUID 和 Image 类型的数据方法 并进行图片存储 还原 中获得 类型的数据方法,并进行图片存储 并进行图片存储,还原 文章分类:.net 编程 文章分类 这些天正好学习 C#,碰到往数据库中插入 GUID,IMAGE 类型的数据问题,BAIDU 了下,找到了解决方法. Java 代码 1 2 3 1.GUID 插入数据库时: string guid=System.Guid.NewGuid().ToString();//或 System.Guid.Empty.ToString(); 4 5 6 7 8 9 //添加主键 SqlParameter fd = new SqlParameter("@字段名", SqlDbType.UniqueIdentifier, 16); fd.Value = new Guid(guid); cmd.Parameters.Add(fd); 从数据库获取时: using (System.Data.IDataReader reader = cmd.ExecuteReader()) 10 if (reader.Read()){ 11 12 } string id = reader["字段名"]; 2.img Java 代码 13 MemoryStream ms = new MemoryStream(); 14 15 16 // 重要! !保存成文件流 pictureBox1.Image.Save("a.bmp"); FileStream fileStream = new FileStream("a.bmp", FileMode.Open, FileAccess.Read); 17 18 19 20 BinaryReader binaryReader = new BinaryReader(fileStream); byte[] int)fileStream.Length); byte img = binaryReader.ReadBytes((int int binaryReader.Close(); fileStream.Close(); 21 这个 img 就是我们需要的 除此之外,还可能需要将图片文件转为 Base64格式 例如: Java 代码 22 //从 pictureBox 中获得文件,并保存,这里的格式可自定义 23 pictureBox1.Image.Save("a.gif"); 24 FileStream fileStream1 = new FileStream("a.gif", FileMode.Open, FileAccess.Read); 25 26 27 28 29 30 31 32 33 34 35 36 37 38 ///
39 40 41 /// 插入文件 ///
/// 文件对象 byte[] inputBytes1 = new byte[fileStream1.Length]; byte byte fileStream1.Read(inputBytes1, 0, System.Convert.ToInt32(fileStream1.Length)); //自定义文件类 TestWork.File file1 = new TestWork.File(); //图片的 Guid file1.FileMainID = guid; //二进制的图片 file1.Data = inputBytes1; //二进制数组的长度 file1.Length = inputBytes1.Length; //调用方法 InsertNormalFileData(file1); 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 /// 库名 /// private static bool InsertFileData(TestWork.File file, string databaseName) { //创建连接对象 SqlConnection con = null null; try { //获取连接对象 con = CreateDataBase(databaseName); //打开连接 con.Open(); //转换格式的 converter System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding(); 58 59 60 61 62 63 //调用存储过程,察看指定文件是否已经存在 cmd.CommandText = "XXXXXXXX"; //创建 SqlCommand 实例 SqlCommand cmd = con.CreateCommand(); 64 65 66 //添加主键:File_Main_ID SqlParameter fileMainID = new SqlParameter("@FILE_MAIN_ID", SqlDbType.UniqueIdentifier, 16); 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 //创建新实例 } //关闭对象 dr.Close(); //判断文件是否存在 if (dr.Read()) { //抛出异常 throw new Exception("指定的文件编号已经存在!"); //获得返回对象 SqlDataReader dr = cmd.ExecuteReader(); //声明命令类型为存储过程 cmd.CommandType = CommandType.StoredProcedure; fileMainID.Value = new Guid(file.FileMainID); cmd.Parameters.Add(fileMainID); 86 87 88 89 90 91 92 //SqlCommand cmd = con.CreateCommand(); //调用 Sp 插入文件,insert into cmd.CommandText = "XXXXXXXXXXXXXXX"; cmd.CommandType = CommandType.StoredProcedure; //创建文件编号对象 //SqlParameter fileMainID = new SqlParameter("@FILE_MAIN_ID", SqlDbType.UniqueIdentifier, 16); 93 94 95 96 97 //创建文件内容对象 //第三个参数为文件大小 SqlParameter data = new SqlParameter("@DATA", //fileMainID.Value = new Guid(file.FileMainID); SqlDbType.Image,file.Data.Length); 98 99 100 101 102 103 SqlDbType.Int, 4); 104 105 length.Value = file.Length; //创建文件大小对象 SqlParameter length = new SqlParameter("@DATA_LENGTH", //转化二进制为 Base64 data.Value = converter.GetBytes(System.Convert.ToBase64String(file.Data)); data.Value = file.Data; 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 } } //添加参数 //cmd.Parameters.Add(fileMainID); cmd.Parameters.Add(data); cmd.Parameters.Add(length); //执行插入操作 int i = cmd.ExecuteNonQuery(); //返回是否插入成功 return i > 0; catch { //抛出异常 throw new Exception("插入文件处理中发生异常"); finally { null) if (con != null { //关闭数据库连接 con.Close(); } 129 130 } } 131 还原图片文件 132 133 134 ///
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 //将 Base64转换为二进制 System.Text.UnicodeEncoding converter = new try { //获取连接对象 con = CreateDataBase(fileMainID); //打开连接 con.Open(); /// 获取原始文件 ///
/// 文件编号 /// 文件实体 public static TestWork.File GetNormalFileData(string fileMainID) { //创建连接对象 SqlConnection con = null null; System.Text.UnicodeEncoding(); 153 154 155 156 157 158 159 160 161 //添加主键:File_Main_ID SqlParameter fd = new SqlParameter("@FILE_MAIN_ID", //调用存储过程,获取文件内容 cmd.CommandText = "XXXXXXXXXXXXXXX"; //创建 SqlCommand 实例 SqlCommand cmd = con.CreateCommand(); SqlDbType.UniqueIdentifier, 16); 162 163 164 165 166 167 168 169 170 171 172 173 //察看是否获得指定 File_Main_ID 对应的文件 if (reader.Read()) { //执行查询操作,获得返回对象 using (System.Data.IDataReader reader = cmd.ExecuteReader()) //声明命令类型为存储过程 cmd.CommandType = CommandType.StoredProcedure; fd.Value = new Guid(fileMainID); cmd.Parameters.Add(fd); 174 175 176 177 178 179 180 //创建文件对象 TestWork.File file = new TestWork.File(); //获取文件编号 file.FileMainID = fileMainID; System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding(); 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 } //返回文件 return file; //获取图片文件类型 file.FormatType = GetFileImageFormat(file.Data); //获取文件大小 file.Length = (int int)reader["Data_Length"]; int //获取文件内容 string da = converter.GetString((byte byte[])reader["Data"]); byte //转换为二进制,用于判断格式和还原 file.Data = Convert.FromBase64String(da); 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 //判定图片格式 } } } } finally { } catch { //如果没有指定的文件 else { //返回 null 对象 null; return null } //抛出异常 throw new Exception("获取原始文件处理中发生异常"); null) if (con != null { //关闭数据库连接 con.Close(); 219 private static TestWork.ImageFormat GetFileImageFormat(byte buffer) byte[] byte 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 //察看格式类型 switch (strFlag) { //JPG 格式 case "255216": return TestWork.ImageFormat.Jpg; //GIF 格式 case "7173": return TestWork.ImageFormat.Gif; //BMP 格式 case "6677": return TestWork.ImageFormat.Bmp; //根据文件头判断 string strFlag = buffer[0].ToString() + buffer[1].ToString(); } { //数据有效性检查 if (buffer == null || buffer.Length < 2) { return TestWork.ImageFormat.Other; 242 243 244 245 246 247 248 249 } } //PNG 格式 case "13780": return TestWork.ImageFo