主题:[原创]实现在fortran 中调用数据库和电子表格读写的理想方法
实现在fortran 中调用数据库和电子表格读写的理想方法
感谢这段时间里 编成爱好者fortran版的各位热心的老师给予我无私的帮助!!
我以前只是简单的学习了一些c语言的内容,对程序一直不是太懂。只是因为毕业设计的原应才与两个月前开始学习fortran。我毕设的内容是要模拟理想的电力市场,并且预测发电厂的发电量和电力市场里面其他的量,里面关于计算的部分已经存在了,我要做的就是让fortran 从数据库里进行读写数据,这样是便于和java 结合,使得可以让用户从网上实时输入数据。
我开始一直以为fortran 不能从数据库里读写数据的,而且网上也有相似的问题,但并没有答案,或者说是实现不了。所以我就准备将已由的程序编译成dll文件,让C++调用。但也有的程序太多了,而且在c++里调用数据库网上提到比较多的就是mfc方法,这样的话或产生界面,而我是不需要界面(界面会有java处理),在win32用c++直接调用数据库我有没有找到具体的例子。(大家有的话可以提供给我,谢谢了)
这时候我都准备放弃了,还好,在编成网上有人提出了用f90SQL可以。
然后我就在实验室的机子上开始尝试,刚开始时用cvf6.5 的,好像感觉并不是很行。实验室刚好这个时候新买了ivf9.1 ,幸运的是f90SQl在那个上面可以,直到这个时候我的毕设才真正的开始,在大家的帮助下,我进展的很快,现在已经差不多完成了。
我想把我在编成的一些经验和问题提出来,和大家一起分享一下:)
首先fortran是可以在数据库和电子表之间进行读写的。而且数据库与电子表的操作完全是一样的
1 调用F90SQL,
http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/117268.aspx
这里可以免费下载f90SQL-lite版
安装:
复制f90SQL library (f90SQL.lib) 到fortran compiler 的LIB路径下, 我是直接在编译路径里面添加的。
复制 f90SQL dynamic link library (f90SQLxxx.DLL) (共2个)到系统目录下,如:WinNT\SYSTEM32 in Windows NT
复制f90SQL modules (f90SQL.f90, f90SQL.mod,共6个) 到fortran compiler 的include/module路径下,我是直接在编译路径里面添加的。
之后就可以调用f90SQL语言进行数据库操作了。 因为使用的是lite版,所以数据库在使用前必须先到Data Sources (ODBC) 里面注册,另外数据库必须是2003或以前的,不支持2007(已测试过)
选用的是access database 和excel表格
从数据库中读取数据:
program main
!load f90SQL modules
use f90SQLConstants
use f90SQL
implicit none
integer(SQLHENV_KIND):: EnvHndl
integer(SQLHDBC_KIND):: ConnHndl
integer(SQLHSTMT_KIND):: StmtHndl
integer(SQLRETURN_KIND):: iRet
character(len=20):: AuthorsStr
integer:: i
!allocate an environment handle
call f90SQLAllocHandle(SQL_HANDLE_ENV, 0, EnvHndl, iRet)
!Set ODBC version, we will be using 3.x in this case
call f90SQLSetEnvAttr(EnvHndl, SQL_ATTR_ODBC_VERSION, &
SQL_OV_ODBC3, iRet)
!Allocate a connection handle
call f90SQLAllocHandle(SQL_HANDLE_DBC,EnvHndl, ConnHndl, iRet)
!Open DSN input
call f90SQLConnect(ConnHndl,'input','Admin','',iRet) ! 数据库DSN名字为input
if (iRet.eq.SQL_SUCCESS .or. iRet.eq.SQL_SUCCESS_WITH_INFO) then
!Allocate statement handdle
call f90SQLAllocHandle(SQL_HANDLE_STMT,ConnHndl, StmtHndl, iRet)
if (iRet.eq.SQL_SUCCESS .or. iRet.eq.SQL_SUCCESS_WITH_INFO) then
!Bind AuthorStr variable to the only column returned by SQL stmt
call f90SQLBindCol(StmtHndl,int(1,SQLSMALLINT_KIND),SQL_F_CHAR, &
AuthorsStr,0,iRet)
!Instruct driver to execute statement
call f90SQLExecDirect(StmtHndl,'SELECT TOP 10 Author from Authors',iRet) !sql的调用语句,Authors为其中的一个表,Author为该表中的栏
print *,'Name of first 10 authors in input database'
!loop through result set and print results to screen
do i=1, 10
call f90SQLFetch(StmtHndl, iRet)
if (iRet.ne.SQL_SUCCESS .and. iRet.ne.SQL_SUCCESS_WITH_INFO) &
exit
!reformat string in AuthorsStr to make it fortran-compatible
call f90SQLStrFormat(AuthorsStr,AuthorsStr)
!print authors
print *, i, ' ', trim(AuthorsStr)
enddo
else
print *,'Error preparing SQL statement'
call ShowDiags(SQL_HANDLE_STMT,StmtHndl)
endif
!release statement handle
call f90SQLFreeHandle(SQL_HANDLE_STMT, StmtHndl, iRet)
!disconnect
call f90SQLDisconnect(ConnHndl,iRet)
else
print *,'Error connecting to data source'
call ShowDiags(SQL_HANDLE_DBC,ConnHndl)
endif
!release connection handle
call f90SQLFreeHandle(SQL_HANDLE_DBC, ConnHndl, iRet)
!release environment handle
call f90SQLFreeHandle(SQL_HANDLE_ENV, EnvHndl, iRet)
stop
end
subroutine ShowDiags(HndlType,Hndl)
!This subroutine prints error diagnostics
!load f90SQL modules
use f90SQLConstants
use f90SQL
implicit none
integer(SQLHANDLE_KIND)::Hndl
integer(SQLSMALLINT_KIND)::HndlType
character(len=6):: SqlState
character(len= SQL_MAX_MESSAGE_LENGTH)::Msg
integer(SQLINTEGER_KIND)::NativeError
integer(SQLSMALLINT_KIND):: iDiag, MsgLen
integer(SQLRETURN_KIND):: DiagRet
iDiag = 1
do while (.true.)
call f90SQLGetDiagRec(HndlType, Hndl, iDiag, SqlState, NativeError, Msg, MsgLen, DiagRet)
if (DiagRet.ne.SQL_SUCCESS.and.DiagRet.ne.SQL_SUCCESS_WITH_INFO) exit
print *,trim(SqlState),',', NativeError,',', Msg(1:MsgLen)
iDiag=iDiag+1
enddo
end subroutine ShowDiags
如果input是电子表格,只需要将call f90SQLExecDirect(StmtHndl,'SELECT TOP 10 Author from Authors',iRet)换成SELECT TOP 10 Y FROM [Sheet1$] 就可以 了(后面会贴出一个例子)
感谢这段时间里 编成爱好者fortran版的各位热心的老师给予我无私的帮助!!
我以前只是简单的学习了一些c语言的内容,对程序一直不是太懂。只是因为毕业设计的原应才与两个月前开始学习fortran。我毕设的内容是要模拟理想的电力市场,并且预测发电厂的发电量和电力市场里面其他的量,里面关于计算的部分已经存在了,我要做的就是让fortran 从数据库里进行读写数据,这样是便于和java 结合,使得可以让用户从网上实时输入数据。
我开始一直以为fortran 不能从数据库里读写数据的,而且网上也有相似的问题,但并没有答案,或者说是实现不了。所以我就准备将已由的程序编译成dll文件,让C++调用。但也有的程序太多了,而且在c++里调用数据库网上提到比较多的就是mfc方法,这样的话或产生界面,而我是不需要界面(界面会有java处理),在win32用c++直接调用数据库我有没有找到具体的例子。(大家有的话可以提供给我,谢谢了)
这时候我都准备放弃了,还好,在编成网上有人提出了用f90SQL可以。
然后我就在实验室的机子上开始尝试,刚开始时用cvf6.5 的,好像感觉并不是很行。实验室刚好这个时候新买了ivf9.1 ,幸运的是f90SQl在那个上面可以,直到这个时候我的毕设才真正的开始,在大家的帮助下,我进展的很快,现在已经差不多完成了。
我想把我在编成的一些经验和问题提出来,和大家一起分享一下:)
首先fortran是可以在数据库和电子表之间进行读写的。而且数据库与电子表的操作完全是一样的
1 调用F90SQL,
http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/117268.aspx
这里可以免费下载f90SQL-lite版
安装:
复制f90SQL library (f90SQL.lib) 到fortran compiler 的LIB路径下, 我是直接在编译路径里面添加的。
复制 f90SQL dynamic link library (f90SQLxxx.DLL) (共2个)到系统目录下,如:WinNT\SYSTEM32 in Windows NT
复制f90SQL modules (f90SQL.f90, f90SQL.mod,共6个) 到fortran compiler 的include/module路径下,我是直接在编译路径里面添加的。
之后就可以调用f90SQL语言进行数据库操作了。 因为使用的是lite版,所以数据库在使用前必须先到Data Sources (ODBC) 里面注册,另外数据库必须是2003或以前的,不支持2007(已测试过)
选用的是access database 和excel表格
从数据库中读取数据:
program main
!load f90SQL modules
use f90SQLConstants
use f90SQL
implicit none
integer(SQLHENV_KIND):: EnvHndl
integer(SQLHDBC_KIND):: ConnHndl
integer(SQLHSTMT_KIND):: StmtHndl
integer(SQLRETURN_KIND):: iRet
character(len=20):: AuthorsStr
integer:: i
!allocate an environment handle
call f90SQLAllocHandle(SQL_HANDLE_ENV, 0, EnvHndl, iRet)
!Set ODBC version, we will be using 3.x in this case
call f90SQLSetEnvAttr(EnvHndl, SQL_ATTR_ODBC_VERSION, &
SQL_OV_ODBC3, iRet)
!Allocate a connection handle
call f90SQLAllocHandle(SQL_HANDLE_DBC,EnvHndl, ConnHndl, iRet)
!Open DSN input
call f90SQLConnect(ConnHndl,'input','Admin','',iRet) ! 数据库DSN名字为input
if (iRet.eq.SQL_SUCCESS .or. iRet.eq.SQL_SUCCESS_WITH_INFO) then
!Allocate statement handdle
call f90SQLAllocHandle(SQL_HANDLE_STMT,ConnHndl, StmtHndl, iRet)
if (iRet.eq.SQL_SUCCESS .or. iRet.eq.SQL_SUCCESS_WITH_INFO) then
!Bind AuthorStr variable to the only column returned by SQL stmt
call f90SQLBindCol(StmtHndl,int(1,SQLSMALLINT_KIND),SQL_F_CHAR, &
AuthorsStr,0,iRet)
!Instruct driver to execute statement
call f90SQLExecDirect(StmtHndl,'SELECT TOP 10 Author from Authors',iRet) !sql的调用语句,Authors为其中的一个表,Author为该表中的栏
print *,'Name of first 10 authors in input database'
!loop through result set and print results to screen
do i=1, 10
call f90SQLFetch(StmtHndl, iRet)
if (iRet.ne.SQL_SUCCESS .and. iRet.ne.SQL_SUCCESS_WITH_INFO) &
exit
!reformat string in AuthorsStr to make it fortran-compatible
call f90SQLStrFormat(AuthorsStr,AuthorsStr)
!print authors
print *, i, ' ', trim(AuthorsStr)
enddo
else
print *,'Error preparing SQL statement'
call ShowDiags(SQL_HANDLE_STMT,StmtHndl)
endif
!release statement handle
call f90SQLFreeHandle(SQL_HANDLE_STMT, StmtHndl, iRet)
!disconnect
call f90SQLDisconnect(ConnHndl,iRet)
else
print *,'Error connecting to data source'
call ShowDiags(SQL_HANDLE_DBC,ConnHndl)
endif
!release connection handle
call f90SQLFreeHandle(SQL_HANDLE_DBC, ConnHndl, iRet)
!release environment handle
call f90SQLFreeHandle(SQL_HANDLE_ENV, EnvHndl, iRet)
stop
end
subroutine ShowDiags(HndlType,Hndl)
!This subroutine prints error diagnostics
!load f90SQL modules
use f90SQLConstants
use f90SQL
implicit none
integer(SQLHANDLE_KIND)::Hndl
integer(SQLSMALLINT_KIND)::HndlType
character(len=6):: SqlState
character(len= SQL_MAX_MESSAGE_LENGTH)::Msg
integer(SQLINTEGER_KIND)::NativeError
integer(SQLSMALLINT_KIND):: iDiag, MsgLen
integer(SQLRETURN_KIND):: DiagRet
iDiag = 1
do while (.true.)
call f90SQLGetDiagRec(HndlType, Hndl, iDiag, SqlState, NativeError, Msg, MsgLen, DiagRet)
if (DiagRet.ne.SQL_SUCCESS.and.DiagRet.ne.SQL_SUCCESS_WITH_INFO) exit
print *,trim(SqlState),',', NativeError,',', Msg(1:MsgLen)
iDiag=iDiag+1
enddo
end subroutine ShowDiags
如果input是电子表格,只需要将call f90SQLExecDirect(StmtHndl,'SELECT TOP 10 Author from Authors',iRet)换成SELECT TOP 10 Y FROM [Sheet1$] 就可以 了(后面会贴出一个例子)