问题总结

最近问题处理方法总结:

1.    ADOQuery 控件加锁机制

对于多线程程序中,会涉及到可能对某张表同时执行数据库的基本操作,此时便要加锁。

具体实现:

Handle select_mutex;

select_mutex = CreateMutex(NULL,false,"selectMutex");

//上锁

            if(WaitForSingleObject(select_mutex,2000)!=WAIT_TIMEOUT)

                     {

                            Try() catch ()…

}

//解锁

ReleaseMutex(select_mutex);

2.    关于多线程使用ADOQuery控件的处理

在不同线程里,建议只使用同一个ADOQuery,并且使用同一个数据库连接对象

3.    EXE执行程序实现不依赖CB安装环境

   CB中,Project -> Options -> Packages -> Build with runtime packages 前面的勾去掉

   附加DLL文件cc3260mt.dll

   附加DLL问价borlndmm.dll

4.    关于代码格式的处理

   注意源码的对齐

   注意源码的缩进

这样既规范,又可以方便大括号的对应

5.    注意判断SQL语句的执行结果

在程序使用ADO控件执行SQL语句时,首先要先判断执行结果,才能进行后面的处理

例如:

If(dm->execSelect(dm->qrySelect, sql)  &&  !dm->qrySelect->Eof )

{….}

Else

{…}

6.    灵活使用try … catch中的异常,通过捕捉异常来进行需要的处理

7.    程序中的SQL语句注意,

如果某字段的值不为字符型,要使用IntToStr或者AnsiString进行转换

8 Select语句和Insert语句的执行方法,

open来执行,返回结果集;  Insert, Update, Delete这些没有返回结果集的SQL语句,使用ExecSQL执行

9.    关于ORA数据库与SQLSERVER数据库重连的方法

判断ORA数据库的连接数据库失败的几种类型:

//分离并判断异常类型,确定异常处理方式

                        AnsiString subexcp = "";

                        subexcp = e.Message.SubString(0,9);

                        if((subexcp == "ORA-03114") ||

                           (subexcp == "ORA-12560") ||

                           (subexcp == "ORA-12170") ||

                           (subexcp == "ORA-12152") ||

                           (subexcp == "ORA-01012") ||

                           (subexcp == "ORA-00028") ||

                                            (subexcp == "ORA-12571")    //增加:包程序写入错误

                          )

判断SQL SERVER数据库连接失败的方法:

sql = "use master; select top 1 * from sysobjects;";

    qry1->Close();

    qry1->SQL->Text = sql;

    try

    {

      qry1->Open();

    }

    catch(...)

    {

      ShowMessage("必须重连!");

      return;

}

 

    对于ORASQL数据库重连:

TADOConnection* newConSendGPS = GetNewConnection(dm->conSendGPS, dm->qrySelect)

        if(newConSendGPS != NULL)

        {

          dm->conSendGPS = newConSendGPS;

          dm->qrySelect->Connection = newConSendGPS;

        }

        else return false;

       //具体处理函数

TADOConnection * __fastcall Tdm::GetNewConnection(TADOConnection* BadDBConnection, TADOQuery *query)

{

        //TADOConnection * newConn = NULL;

TADOConnection* newConn = new TADOConnection(NULL);    //20090227修改,这里产生数据库重连失败的原因

        int times = 0;

 

        //AnsiString sql = "use master; select top 1 * from sysobjects;";

        AnsiString sql = "select * from dual";

        bool  flag = false;

        //while(true){

        while(!flag){

          try

          {

//            if(++times > 10)

//            {

//              return NULL;

//            }

            if(newConn == NULL) newConn = BadDBConnection;

            newConn->Close();

            newConn->ConnectionString = BadDBConnection->ConnectionString;

            newConn->Connected = true;

            newConn->KeepConnection = true;

            query->Connection = newConn;

            query->Close();

            query->SQL->Clear();

            query->SQL->Add(sql);

            //query->ExecSQL();

            query->Open();

            dm->logInfo("/n重连数据库成功!");

            //delete BadDBConnection;

            flag = true;

            break;

          }

          catch(Exception &e)

          {

            dm->logInfo("/n重连数据库失败:%s", e.Message.c_str());

            dm->logInfo("/n数据库重连...");

            Sleep(3000);

            //flag = false;

            //return true;

          }

        }       

        return newConn;

}

 

   只针对SQL数据库重连

// 重连数据库,只针对SQLSERVER数据库

bool __fastcall Tdm::ResetDBConnection(TADOConnection *BadDBConnection)

{

        //打印到log信息

        dm->logInfo("/n数据库连接出现异常,程序暂停,等待重连...");

        //AnsiString connStr = BadDBConnection->ConnectionString;

        //连接数据库

        BadDBConnection->Close();

BadDBConnection->Connected = false;  //一定要加这行代码,否则ADO查询控件无法使用

        while(!BadDBConnection->Connected)

        {

                try

                {

                  //BadDBConnection->Close();

                  //BadDBConnection->ConnectionString = connStr;

                  BadDBConnection->Connected = true;

                  //BadDBConnection->KeepConnection = true;

                }

                catch(...)

                {

                        BadDBConnection->Connected = false;

                        dm->logInfo("重新连接数据库异常...");

                        Sleep(3000);

                }

 

        }

        //打印log信息

        dm->logInfo("/n重连数据库成功");

        return true;

}

 

 

10.sysdate - 1/8640含义

表示当前时间的1秒, 1/24/60/60

11. 当出现ORA-12514:无法识别的数据库连接字符串时

是因为程序所在的文件夹带有括号,请特别注意。

强烈建议:程序文件夹最好不要用括号或者中文字体之类,应该使用规范的英文命名。

 

12. 数据库连接字符串

1. 对于SQL SERVER数据库

       conDB->Close();

        conDB->ConnectionString ="Provider=SQLOLEDB.1;Password=" +

        (WideString)lpPass + ";Persist Security Info=True;User ID=" + lpUserID +

        ";Initial Catalog=" + lpDataBase + ";Data Source="+lpSqlServer;

 

"Provider=SQLOLEDB.1;Password=sasa1234;Persist Security Info=True;User ID=sa;Initial Catalog=fyc;Data Source=192.168.32.6"

 

 

 

 

 

 

2. 对于ORACLE数据库

       conDB->Close();

        conDB->ConnectionString ="Provider=OraOLEDB.Oracle.1;Password=" +

        (WideString)lpPass + ";Persist Security Info=True;User ID=" + lpUserID +

        ";Data Source=" + lpDataBase + ";Extended Properties=''";

 

"Provider=OraOLEDB.Oracle.1;Password=watermon;Persist Security Info=True;User ID=watermon;Data Source=Dev;Extended Properties=''"

 

13. oracle怎样修改表名、列名、字段类型、添加表列、删除表列

ALTER TABLE 表名 RENAME TO  新表名 --修改表名

ALTER TABLE 表名 RENAME COLUMNNAME TO NAME1 --修改表列名

ALTER TABLE 表名 MODIFY NAME1 NUMBER(20)  --修改字段类型

ALTER TABLE 表名 ADD    列名 VARCHAR2(40) --添加表列

ALTER TABLE 表名 DROP   COLUMN COLUMNNAME --删除表列

 

复制表: create table new_table as select * from knowed_table

 

14.  关于使用logInfo

a.         包含 logdll.dll,  logdll.lib logdllapi.h

b.         在头文件定义Hlog logHandle

c.         cpp文件添加logInfo函数

 

15.  关于使用memcpy的一个例子

memcpy(++msg, FilePathName.c_str(), FilePathNameLength);

msg += FilePathNameLength - 1;

16.  如何生成文件

//定义文件指针(需要包含头文件#include <stdio.h>)

FILE *fp;

//打开文件

fp = fopen(FilePathName.c_str(), "a+");

//输出到文件

fprintf(fp, Msg.c_str());

//关闭文件

fclose(fp);

17.  如何定义全局变量指针

main函数的前面定义int *pointer = (int *)malloc(5);或者 int *pointer = new int;

在要使用全局变量的类的头文件中定义extern int *pointer;     //引用全局变量

 

18TerminateThread()的使用

A thread cannot protect itself against TerminateThread, other than by controlling access to its handles.

不能在一个线程里面执行TerminateThread().

       if(rHandle)

        {

          DWORD lpExitCode;

          if(::GetExitCodeThread(rHandle, &lpExitCode))

          {

            if(lpExitCode == STILL_ACTIVE)

            {

              printf("/nlpExitCode = %d", lpExitCode);

              //线程还在运行

              printf("/n线程还在运行");

              //SetEvent(m_hEventClose);

              //WaitForMultipleObjects(1, &m_hEventCloseEd, TRUE, INFINITE);

            }

            else

            {

              printf("/n线程已经结束");

            }

          }

        }

       if(rHandle)

        {

                 TerminateThread(rHandle, 0);

                 CloseHandle(rHandle);

                 rHandle = NULL;

                 ComDataModule->logInfo("/n关闭线程成功");

        }

19.数据库连接字符串

1. 对于SQL SERVER数据库

       conDB->Close();

    conDB->ConnectionString ="Provider=SQLOLEDB.1;Password=" +

        (WideString)lpPass + ";Persist Security Info=True;User ID=" + lpUserID +

        ";Initial Catalog=" + lpDataBase + ";Data Source="+lpSqlServer;

 

"Provider=SQLOLEDB.1;Password=sasa1234;Persist Security Info=True;User ID=sa;Initial Catalog=fyc;Data Source=192.168.32.6"

 

 

2. 对于ORACLE数据库

       conDB->Close();

        conDB->ConnectionString ="Provider=OraOLEDB.Oracle.1;Password=" +

        (WideString)lpPass + ";Persist Security Info=True;User ID=" + lpUserID +

        ";Data Source=" + lpDataBase + ";Extended Properties=''";

 

"Provider=OraOLEDB.Oracle.1;Password=watermon;Persist Security Info=True;User ID=watermon;Data Source=Dev;Extended Properties=''"

 

20. 安装SQLSERVER数据库出现的问题导致无法安装

问题描述:

     SQL Server 2005 卸载之后重新安装,在执行检查时报:对性能监视器计数器注册表值执行系统配置检查失败。有关详细信息,请参阅自述文件或 SQL Server 联机丛书中的“如何在 SQL Server 2005 中为安装程序增加计数器注册表项值”。

解决方案:

在开始==>运行==>regedit.exe ,在注册表里找 HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Perflib 里面有 Last Counter  Last Help 选项查看其相应的值之后。如果你安装中文版HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Perflib/004里面找到  Counter Help  查看它们的最大值 ,在它们的最大值基础上加2赋给Last CounterLast Help 确定即可,无需重启。 如果你安装的是英文版,在HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows

NT/CurrentVersion/Perflib/009里找到 Counter Help  查看它们的最大值,执行上面的操作即可

21   如何写SQL SERVER数据库的update触发器

1update触发器中可以用两个系统表 分别是 inserted deleted

2inserted表中存这更新后的所有数据

3deleted 存着更新前的所有数据

4update(列名字)可以测试一个列是否被更新了

有了上面的知识,写update触发器就一切ok了。

22   如何写SQL SERVER数据库里创建表的SQL语句

创建新表的同时复制数据:             

select * into gpsinfo_20090506  from alarmstatus

只创建新表,没有复制数据:

select * into gpsinfo_20090502 from alarmstatus where 1 = 0

创建新表的同时有条件地复制数据

select * into gpsinfo_20090502 from alarmstatus where uniqueid > 1

如果表存在,复制表数据(源表和目标表不能有自增变量)

insert into alarmstatus_1 (terminalcode, status) select terminalcode, status from alarmstatus_2

或者insert into insert into alarmstatus_1 select * from alarmstatus_2

23   如何在SQL SERVER数据库里判断某表是否存在

select count(*) as qty from dbo.sysobjects where name = 'gpsinfo_20090501'

select count(*)  qty from dbo.sysobjects where name = 'gpsinfo_20090501';

qty=0 不存在

qty=1 存在

注意:不能使用select * from gpsinfo_20090501方式来查询,否则会造成对象名无效的错误

 

24.  gettickcount()的用法

用于计算时间,相当于计时器。当达到计时效果时,要注意重置计时为当前时间,开始重新计时。

25.  移位

Int value = 1899932 -----1CFD9C

使用三个字节表示

Char cvalue[0] = 0x1c;

Char cvalue[1] = 0xfd;

Char cvalue[2] = 0x9c;

 

1

(value >>16)  &  0xff

>>16:右移16位,即2个字节占用的位置,去掉低16位的数值,即得到0x1c

& 0xff 0x001c

              &0x00ff

        _________

                     0x1c

2

(value >>8)  &  0xff

>>8:右移8位,即1个字节占用的位置,去掉低8位的数值,即得到0xfd

& 0xff 0x00fd

              &0x00ff

        _________

                     0xfd

3

Value & 0xff

& 0xff  0x009c

              &0x00ff

        _________

                     0x9c

26.  int,long int, unsigned int,unsigned long int,long long的表示范围问题

intlong int二者的范围是一致的,都是-2^31---2^31-1,能表示的最大值是0x7FFFFFFF;

unsigned intunsigned long int二者的范围也是一致的,都是0---2^32-1,能表示的最大值是0xFFFFFFFF;

long long 使用的意义:

long long a;

 a = atoi(inputdata);

 if(a<0x1 || a>0xFFFFFFFF)

 return BOOL_FALSE;

在这里,当用户恰好输入0xFFFFFFFF这个值时,程序就不会认为它是非法的。但是当使用int a或者unsigned int a时程序将会认为非法输入。

27.  关键字static 的作用是什么?

这个简单的问题很少有人能回答完全。在C 语言中,关键字static 有三个明显的作用:

在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。

在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。

在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。

28. 几种变量的定义

a)    int a;

b)    int *a;

c)    int **a;

d)    int a[10];

e)    int *a[10];

f)     int (*a)[10];

g)    int (*a)(int);

h)    int (*a[10])(int);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值