‘壹’ OTL操作数据库如果数据库语句错误怎么判断
请查api命令表,话说你得先学下sql的操作规范。
‘贰’ vc6.0与oracle编程采用什么方式最好
肯定最好使用otl(Oracle, Odbc and DB2-CLI Template Library),它直接用oracle提供的oci接口访问oracle(直接调用oracle的API),采用流操作,速度最快,与C语言直接调用API相当。具体可查询otlv4.168.h。
同时也是跨平台的,也不需要ADO组件以及.net framework 等
‘叁’ VC中如何正确使用ADO
数据库与数据库编程:
当前各种主流数据库有很多,包括Oracle, MS SQL Server, Sybase, Informix, MySQL, DB2,
Interbase / Firebird, PostgreSQL, SQLite, SAP/DB, TimesTen, MS ACCESS等等。
数据库编程是对数据库的创建、读写等一列的操作。数据库编程分为数据库客户端编程与数据库服务器端编程。数据库客户端编程主要使用ODBC API、ADO、ADO.NET、OCI、OTL等方法;数据库服务端编程主要使用OLE DB等方法。
数据库编程需要掌握一些访问数据库技术方法,还需要注意怎么设计高效的数据库、数据库管理与运行的优化、数据库语句的优化。
ADO编程的一般步骤:
创建一个Connection对象
打开数据源,建立同数据源的连接
执行一个SQL命令
使用结果集
终止连接
ADO最重要的三个对象:
连接对象(Connection)
命令对象(Command)
记录集对象(RecordSet)
在使用这三个对象的时候,需要定义与之相对应的智能指针:_ConnectionPtr、_CommandPtr、_RecordsetPtr
使用智能指针要:定义指针变量、创建其实例(实例化)、调用方法和属性。该智能指针在析构对象时,自动调用Release方法,即使用后不需要手动释放内存,代码更加简洁。
但需要调用Close方法,关闭连接Connection或者记录集RecordSet。
‘肆’ 哪一种编程语言适合人工智能
LISP:是一门高级的语言,在人工智能中备受青睐,因为它具备垃圾收集、动态类型、数据函数、统一语法、交互式环境、可扩展性等特性,所以非常适合人工智能编程。
PROLOG:提供了针对关于逻辑相关问题的解决方案,或者说它的解决方案有着简洁的逻辑特征,主要缺点就是学习起来很难。
C/C++:主要用于对执行速度要求很高的时候,它主要用于简单程序,统计人工智能,如神经网络就是一个常见的例子。
java:使用了LISP中的几个理念,最明显的就是垃圾收集,它的可移植性使它可以适用于任何程序,它还有一套内置类型,Java没有LISP和Prolog高级,又没有C那样快,但如果要求可移植性它是最好的。
Python:是一种用LISP和Java编译的语言,按照比较,这两种语言彼此非常相似,仅有一些细小的差别;还有JPython,提供了访问Java图像用户界面的途径,这是PeterNorvig选择用JPyhton翻译他人工智能书籍中程序的的原因,JPython可以让他使用可移植的GUI演示,和可移植的http/ftp/html库,所以它非常适合作为人工智能语言。
综合情况来讲,Python更适合人工智能编程,因为Python具有优质的文档、设计非常好、快速、坚固、可移植、可扩展等,这些对于人工智能而言都是非常重要的因素。
‘伍’ 我是高中生,学编程入门要看什么书
不同意楼上说的。我建议先学VB,比较简单。等差不多掌握编程思想后再学C,进而C++或者java。
C语言是面向过程的语言,程序界面不够友好,适合编对人机交互性要求不高的程序。而且C语言涉及到指针操作和大量算法,对于高中学生有些难。而VB是完全面向对象的语言,用户界面设置简单友好,编程效率高,编译器使用也比较人性化,非常适合初学者。
‘陆’ 欧太力k801门禁说明书OTL K801门禁使用说明书 谁有 我想添加ID卡
摘要 你好,初始编程密码是*9999#。
‘柒’ 求助大牛!C++编程,如何查询数据库中多条记录的多个字段值,并且返回到一个数据块中...急急急!
额。。写个个简单的样列,用的是ODBC,比较直接。使用ADO的话虽然代码少,但是看起来不是很好理解。你可以自己去网络学学~
用到的函数都比较容易理解,我就没多加说明了,如果有不理解的复制函数名网络一下,会有详细的说明的。大概的流程就是这样了~
//包含头文件
#include "windows.h"
#include "sqlext.h"
#pragma comment(lib,"odbc32.lib")
int main(int argc, char* argv[]){
//1.连接数据源(前提是你已经配置好了数据源,我用的sqlserver数据库,怎么配数据源网络一下~很简单的)
//分配环境句柄, 保存一些驱动程序的信息
SQLHENV henv;//环境句柄
SQLRETURN sqlRet;
sqlRet = SQLAllocEnv(&henv);
if (sqlRet != SQL_SUCCESS && sqlRet != SQL_SUCCESS_WITH_INFO)
{
printf("分配环境句柄失败!\n");
return -1;
}
//分配连接句柄
SQLHDBC hdbc;//连接句柄
sqlRet = SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc);
if (sqlRet != SQL_SUCCESS && sqlRet != SQL_SUCCESS_WITH_INFO)
{
printf("分配连接句柄失败!\n");
return -1;
}
//连接数据源(test是数据库名字,sa 和sa 是用户们和密码,你替换即可)
sqlRet = SQLConnect(hdbc,(SQLCHAR*)"test",strlen("test"),(SQLCHAR*)"sa",2,(SQLCHAR*)"sa",2);
if (sqlRet != SQL_SUCCESS && sqlRet != SQL_SUCCESS_WITH_INFO)
{
printf("连接数据源失败!\n");
return -1;
}
//2.执行SQL语句
//准备语句句柄
SQLHSTMT hstmt;
sqlRet = SQLAllocHandle(SQL_HANDLE_STMT,hdbc,&hstmt);
if (sqlRet != SQL_SUCCESS && sqlRet != SQL_SUCCESS_WITH_INFO)
{
printf("连接语句句柄失败!\n");
return -1;
}
//设置游标类型(参看:http://blog.csdn.net/bichenggui/article/details/5601381)
sqlRet = SQLSetStmtOption(hstmt,SQL_ATTR_CURSOR_TYPE,SQL_CURSOR_KEYSET_DRIVEN);
if (sqlRet != SQL_SUCCESS && sqlRet != SQL_SUCCESS_WITH_INFO)
{
printf("设置光标类型失败!\n");
return -1;
}
//执行SQL语句
//直接执行(你替换成你自己的sqlserver语句即可)
sqlRet = SQLExecDirect(hstmt,(SQLCHAR*)"insert into student values('lsk',21)",SQL_NTS);
if (sqlRet != SQL_SUCCESS && sqlRet != SQL_SUCCESS_WITH_INFO)
{
printf("执行SQL语句失败!\n");
return -1;
}
//获取结果集
SQLCHAR value[20]={0};
SQLINTEGER len = 0;
//移动光标(不移动前光标指向结果集第一列的前面)
SQLFetch(hstmt);
//取值(取的是结果集的第一列的值),第二个参数表示取第几列
SQLGetData(hstmt,1,SQL_C_CHAR,value,20,&len);
printf("结果为:%s\n",value);
//假如结果集有多行则再次移动光标即可
SQLFetch(hstmt);
//然后再次取值
SQLGetData(hstmt,1,SQL_C_CHAR,value,20,&len);
//关闭句柄,释放资源
SQLFreeHandle(SQL_HANDLE_STMT, hstmt); //释放语句句柄
SQLDisconnect(hdbc); //断开连接
SQLFreeHandle(SQL_HANDLE_DBC, hdbc); //释放连接句柄
SQLFreeHandle(SQL_HANDLE_ENV, henv); //释放环境句柄
return 0;
}
‘捌’ 十万火急~~求教OTL 我修改了N遍还是有错,请问像我这样 函数调用,指针,数组该怎么处理呀
void main()
{void sort(int a[],int q);///////////////////////////////这里最后少一个分号
。。。
sort(*p,i);///////////////////调用函数写的不对,int sort(struct st *p,int i)改为sort(*p,i)
。。。
}
void sort(int a[],int q)//这里的参数q和下面的临时变量q重复了,需要改一下
{int j,q;
int t;
for(j=0;j<0;j++)
for(q=0;q<9-j;q++)
if (a[q]<a[q+1])
{t=a[q];a[q]=a[q+1];a[q+1]=t;}
return (a[q]);
}
‘玖’ 下面这些OCI函数到底是在哪个lib库中实现的用的是ORACLE11g
一、开始前的准备工作
在使用OTL进行编程之前,要首先确定使用的Oralce版本以及所选用的字符集。OTL支持目前几乎所有的主流数据库,可以通过宏启用otlv4.h中对应的数据库操作接口。
如:使用Oracle 11g R2、字符集选择UTF8,则可在包含otlv4.h之前声明以下两个宏:
#define OTL_ORA11G_R2
#define OTL_ORA_UTF8
#include "otlv4.h"
....
二、常用类及其常用成员
1. otl_connect类
static int otl_initialize(const int threaded_mode=0):
用于初始化OTL环境的静态函数,参数指定是用于多线程还是单线程。它不保证线程安全,也就是说,如果多个线程共享使用一个otl_connect对象,需要加锁进行控制。有个同事因为在多线程环境下使用了默认的参数0,就导致了程序异常。但是单线程环境下,参数设1是没有问题的。所以,可以考虑将此参数直接设为1。
void rlogon(...):
这个函数有多个版本,请注意参考官方文档中与相应数据库版本对应的函数声明。11g中用到的参数说明如下:
const char *connect_str:连接字符串,格式为:"用户名/密码@数据库服务名"
const int aauto_commit:自动提交模式。若此参数设为0(默认),则通过此连接对象执行的事务不会自动提交。如使用direct_exec执行删除记录的操作时,需要手动调用commit()成员函数提交事务;若设为1则通过此otl_connect对象开启的事务会自动提交。
long direct_exec(...):
const char *sqlstm: 指定所要执行的“静态SQL语句”,即不产生输入或输出的SQL语句。如delete from book where name='c++‘ 。但是不能执行如select sysdate from al或select * from book亦或delete from book where name=:f1之类的语句,因为它们会带有输入或输出,此类SQL语句可以通过otl_stream实现,下面会有介绍。
int ignore_error:是否忽略异常。可以指定otl_exception::disable禁用异常,否则程序需要使用try...catch(otl_exception &e)...捕获并处理异常。
int connected:
此成员变量标识了连接对象是否连接成功,一旦连接成功其值即为1。即便后来网络断掉了,此值仍旧保持不变,logoff()后此值变为0。所以此变量只能用于检查rlogon是否连接成功,而不能判断当前与数据库的连接是否正常。
2. otl_stream类
void open(...):
为流对象关联一个SQL语句,可以是带输入或输出的SQL语句或PL/SQL块。
const int arr_size:指定流缓冲区的大小。作为输出流使用时,若输出缓冲区中的记录数达到此值即缓冲区满时,会自动刷新缓冲区,若已设设置了自动提交则一并提交数据(默认);
const char *sqlstm:SQL语句,可以指定绑定变量,如:delete from book where id = :f1 and price = :f2;
otl_connect &db:流所使用的数据库连接对象。
void set_commit(int auto_commit=0):
设置流被刷新时否自动提交事务。两种条件下流会被刷新:a.缓冲区满 b.手动调用flush成员函数
void flush(...):
执行和流关联的SQL语句。如执行:
otl_stream delStream;
delStream.open(100, delete from book where id = :f1 and price = :f2, dbConnect); //正常情况下向流中加入100条记录时才执行删除
delStream << 1;
delSteam << 'C++';
delStream.flush(); //立即执行删除操作,尽管当前流中只有一条记录
long get_rpc():
获取流中SQL语句执行后所影响到的记录数,如插入100条记录,则调用此函数返回的即为100
int good():
判断流对象是否已正常打开,已打开返回1。注意:若复用一个流对象时,必须先调用close函数将其关闭,然后再调用open重新打开。
int get_dirty_buf_len():
获取当前流对象缓冲区中的记录数,其最大值为缓冲区size-1。每当缓冲区满时会自动刷新,刷新后再调用此函数时返回0
3.otl_exception类
该类的几个成员用于表示异常的信息,如:
char stm_text[2048]:出错的SQL语句;
char var_info[256]:若在流中使用了与实际类型不符的绑定变量,此数组的值为绑定变量的信息;
unsigned char msg[1000]:这个我比较喜欢用,此数组显示出具体的异常信息(包括oracle返回的错误码),如连接超时等等。
三、对于网络异常的处理
现在项目对于程序的异常处理能力要求越来越高,比如网络中断或数据库出现异常等,要求在故障恢复后,程序能正常与数据库保持连接,使业务尽可能的少受影响。可以通过以下方法解决此种情况。这也是折磨了我两天的一个问题:(
首先,程序要在提交数据的地方使用try...catch捕获otl_exception异常,当提交失败时,otl会抛出此异常并携带异常信息;
其次,要在捕获到异常之后,关闭之前的连接对象(如果有流使用此连接对象,则一定要先关闭流对象,然后再断开otl_connect对象);
最后,重新连接数据库并再次初始化流对象。
如:
void ReConnect(otl_connect &otlConnect, const char *pConnStr, int iAutoCommit);
....
//声明otl对象并初始化对象
otl_connect dbConn;
otl_stream outStream;
void Init(void)
{
try
{
otl_connect::otl_initialize(1);
dbConn.rlogon("test1/password@testdb");
outStream.open(100, "insert into book values(:f1, :f2, :f3, :f4)", dbConn);
outStream.set_commit(1);
}
catch (otl_exception &e)
{
//处理异常
}
}
//提交数据的函数
void Submit(void)
{
try
{
for (int i = 0; i < 5000; i++)
{
outStream << i;
outStream << "abc";
outStream << i;
outStream << "null";
}
}
catch(otl_exception &e)
{
//提交数据异常,重新连接数据库并重新初始化流对象
outStream.close(); //必须先关闭流对象。若先断开连接会出现关闭流对象时报OCIHandleFree异常导致流对象无法正常关闭引起内存泄漏
ReConnect(dbConn, "test1/password@testdb", 0);
outStream.open(100, "insert into book values(:f1, :f2, :f3, :f4)", dbConn);
outStream.set_commit(1);
}
}
//重新连接连接数据库函数
void ReConnect(otl_connect &otlConnect, const char *pConnStr, int iAutoCommit)
{
if (1 == otlConnect.connected)
{
otlConnect.logoff();
}
Retry:
try
{
otlConnect.rlogon(pConnStr, iAutoCommit);
}
catch (otl_exception &e)
{
Sleep(1000);
goto Retry;
}
}
这样,调用Submit函数提交数据时,就有了网络异常处理功能,若提交失败则会一直尝试重新连接,直到连接成功为止。
‘拾’ otl编程中(oracle) insert中对于date型字段怎么给值呀,知道用sysdate,具体怎么弄呀
tk_idate=sysdate