VC++技术

MySQL的insert、replace和update语句执行效率

测试程序

#include <stdio.h>

#include <stdlib.h>

#include <string>

#include <iostream>

#include <time.h>

#include "/usr/local/include/mysql/mysql.h"

using namespace std;

MYSQL mysql;

void exiterr(int exitcode)

{

         printf("%s\n", mysql_error(&mysql));

         exit( exitcode );

}

// create ip, from 10.0.0.0~10.0.255.255

void init_ip()

{

         string insert_sql;

       

         string ip;

         char vbuf1[5];

         char vbuf2[5];

         for(int i=0; i<=255; i++){

                   for(int j=0; j<=255; j++){

                            ip = "10.0.";

                            memset(vbuf1,0,sizeof(vbuf1));

                            sprintf(vbuf1,"%d.",i);

                            ip.append(vbuf1);

                            memset(vbuf2,0,sizeof(vbuf2));

                            sprintf(vbuf2,"%d",j);

                            ip.append(vbuf2);

                          

                            // 以下是测试语句

                            //insert_sql = "replace into test_data(ip,mobilenum) values('";

                            //insert_sql += ip + "','13200000001')" ;

                            insert_sql = "update test_data set mobilenum='13200000002' where ip='" + ip + "'";

                            if (mysql_query(&mysql,insert_sql.c_str())) exiterr(3);

                   }

         }

}

int main()

{

         int i = 0;

         time_t  timeVal;

         printf("************* begin mysql operation *****************\n");

         mysql_init(&mysql);

       

         if(!mysql_real_connect(&mysql,"192.168.0.100","user","pass","testDB",0,NULL,0)){

                   printf("connect to db error,%s\n", mysql_error(&mysql));

                   return 1;

         }

         time(&timeVal);

         cout << "begin time: " << timeVal << endl;

         init_ip();

         time(&timeVal);

         cout << "end time: " << timeVal << endl;

         mysql_close(&mysql);

         printf("************* end mysql operation *****************\n");

         return 0;

}

表结构:

CREATE TABLE gtpDB.test_data(

  ip varchar(15) NOT NULL,

  mobilenum varchar(11) NOT NULL,

  gtptime int(10) UNSIGNED NOT NULL,

  PRIMARY KEY (Ip),

  INDEX (Ip)

) TYPE=MyISAM;

操作数据表数据条数:65536

1、insert测试

         insert_sql = "insert into test_data(ip,mobilenum) values('";

         insert_sql += ip + "','13200000001')" ;

         执行时间:10s

2、replace测试

使用REPLACE插入一条记录时,如果不重复,REPLACE就和INSERT的功能一样,如果有重复记录,REPLACE就使用新记录的值来替换原来的记录值。使用REPLACE的最大好处就是可以将DELETE和INSERT合二为一,形成一个原子操作。这样就可以不必考虑在同时使用DELETE和INSERT时添加事务等复杂操作了。在使用REPLACE时,表中必须有唯一有一个PRIMARY KEY或UNIQUE索引,否则,使用一个REPLACE语句没有意义。

2.1、表空时的测试

         清除表中数据,此时相当于insert操作

         insert_sql = "replace into test_data(ip,mobilenum) values('";

         insert_sql += ip + "','13200000001')" ;

         执行时间10s

2.2、表不空时的操作,即此时有65536条数据

         紧接着2.1测试

         insert_sql = "replace into test_data(ip,mobilenum) values('";

         insert_sql += ip + "','13200000002')" ;

         此时相当于要修改原有的mobilenum数据

         执行时间:10S

3、update测试

         紧接着2.2,表不空时,更新数据

insert_sql = "update test_data set mobilenum='13200000003' where ip='" + ip + "'";

执行时间:15s


【结论】:replace效率不错,且概括了insert和delte/insert功能。

vc 关闭进程

终止指定进程 

#include "tlhelp32.h" 

void KillExe(const char* szExeName) 

if (szExeName == NULL) 
return 0; 
int lsr = lstrlen(szExeName); 
if (lsr == 0) 
return 0; 

PROCESSENTRY32 my; 
HANDLE l = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
if (((int)l) != -1) 

my.dwSize = sizeof(my); 
if (Process32First(l, &my)) 

do 

if (lstrcmpi(szExeName, my.szExeFile + lstrlen(my.szExeFile) - lsr) == 0) 

HANDLE hProcessHandle; 
hProcessHandle = OpenProcess(0x1F0FFF, true, my.th32ProcessID); 
if (hProcessHandle != NULL) 

if (TerminateProcess(hProcessHandle, 0) != NULL) 

CloseHandle(hProcessHandle); 


CloseHandle(l); 
return; 

}while (Process32Next(l, &my)); 

CloseHandle(l); 

}



调用方式 
KillExe("c:\\windows\\notepad.exe"); 

完整或部分路径名,不区分大小写

设置属性的函数SetFileAttributes用法

我们拷贝的文件,往往为了隐藏或者是加入需要加入新的属性设置,哪么设置属性的函数就是这个函数了SetFileAttributes。现在让我来认真的分析一下这个函数吧。
VC函数原型:
BOOL SetFileAttributes(
  LPCTSTR lpFileName,
  DWORD dwFileAttributes
);

VC函数参数说明:
lpFileName LPCTSTR 文件名所在地址的字符
dwFileAttributes DWORD 给文件设置的相应属性
 设置属性值的说明:
 FILE_ATTRIBUTE_HIDDEN  隐藏
 FILE_ATTRIBUTE_ARCHIVE 存档
 FILE_ATTRIBUTE_NORMAL 普通
 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
 FILE_ATTRIBUTE_OFFLINE
 FILE_ATTRIBUTE_READONLY 只读
 FILE_ATTRIBUTE_SYSTEM  系统文件
 FILE_ATTRIBUTE_TEMPORARY

VC函数返回值:
如果设置成功返回非零值(TRUE),否则返回零值(FALSE);

VC函数源代码:

if (CopyFile(FileData.cFileName, szNewPath, FALSE))
{
dwAttrs = GetFileAttributes(FileData.cFileName);
if (dwAttrs==INVALID_FILE_ATTRIBUTES) return;

if (!(dwAttrs & FILE_ATTRIBUTE_READONLY))
{
SetFileAttributes(szNewPath,
dwAttrs | FILE_ATTRIBUTE_READONLY);
}
}
else
{
printf("Could not copy file.n");
return;
}


 

bResult = ::SetFileAttributes(L"123.txt", FILE_ATTRIBUTE_ARCHIVE); if(!bResult) { DWORD dwErr = GetLastError(); } ///////////////////////////////////////////////////////////////////////////////////////////////本人实例:
//写入bin二进制数据
CString strPath(_T("D:\\PCDatabase\\GSMSet.bin"));
//先将文件属性设置为普通文件
::SetFileAttributes(strPath,FILE_ATTRIBUTE_NORMAL);
//写入数据
WriteItem(strPath,&SetArray);

//修改文件时间属性:创建时间 修改时间 访问时间
ModifyFileTime();

//再设置文件属性为隐藏 只读和系统文件
::SetFileAttributes(strPath,FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM);

//MessageBox(strLacID+strTime+strHostID+strLacCount+strbThread+strGSMErrorCount+strSimID,"写入BIN数据",MB_OK);
MessageBox("GSMSet配置文件写入成功!","BELSON",MB_OK);


 

vc删除文件夹

//功能: 删除非空目录文件夹
//输入: DirName 文件夹名
//输出: 删除是否成功
//功能: 迭代文件夹内文件,一个一个删除
BOOL DeleteDirectory(char *DirName)
{
 CFileFind tempFind;
 char tempFileFind[200];
 sprintf(tempFileFind,"%s\\*.*",DirName);
 BOOL IsFinded=(BOOL)tempFind.FindFile(tempFileFind);
 while(IsFinded)
 {
  IsFinded=(BOOL)tempFind.FindNextFile();
  if(!tempFind.IsDots())
  {
   char foundFileName[200];
   strcpy(foundFileName,tempFind.GetFileName().GetBuffer(200));
   if(tempFind.IsDirectory())
   {
    char tempDir[200];
    sprintf(tempDir,"%s\\%s",DirName,foundFileName);
    DeleteDirectory(tempDir);
   }
   else
   {
    char tempFileName[200];
    sprintf(tempFileName,"%s\\%s",DirName,foundFileName);
    DeleteFile(tempFileName);
   }
  }
 }
 tempFind.Close();
 if(!RemoveDirectory(DirName))
 {
  MessageBox("删除目录失败!","警告信息",MB_OK);
  return FALSE;
 }
 return TRUE;
}

Web Brower 模拟浏览器 post方式提交代码

HRESULT GetPostData(LPVARIANT pvPostData)
{
HRESULT hr;
LPSAFEARRAY psa;
LPCTSTR cszPostData = "type=1&system=4&task=100&status=-1&num=1&data=http%3A%2F%2Fsina.com.cn%0A";// w=企业&y=3;donotcheckip=1&keys=卫浴洁具,玫瑰暗香
UINT cElems = lstrlen(cszPostData);
LPSTR pPostData;

if (!pvPostData)
{
return E_POINTER;
}

VariantInit(pvPostData);

psa = SafeArrayCreateVector(VT_UI1, 0, cElems);
if (!psa)
{
return E_OUTOFMEMORY;
}

hr = SafeArrayAccessData(psa, (LPVOID*)&pPostData);
memcpy(pPostData, cszPostData, cElems);
hr = SafeArrayUnaccessData(psa);

V_VT(pvPostData) = VT_ARRAY | VT_UI1;

V_ARRAY(pvPostData) = psa;
return NOERROR;
}


void CGetdeswordDlg::OnOK()
{
UpdateData(TRUE);


// m_StrEdit = "http://192.168.14.249/np/portal/portlets";
if (!m_StrEdit.IsEmpty())
{

VARIANT postData;
HRESULT hr;
hr = GetPostData(&postData);

m_web.Navigate (m_StrEdit, 0, 0, &postData, 0);

// m_web.Navigate (m_StrEdit, 0, 0, 0, 0);
}
}
一样发送并不成功,主要是Navigate 最后一个参数没有设对.需要定义vHeaders


定义方法参看下面的案例

具体参数细节请参看MSDN文档。比较麻烦的是这个函数的参数设置,后面作详细说明,先看代码。这里有如下假定
iBrowser是一个有效的IWebBrowser2指针,
url为有效的地址(如:L"http://172.24.1.241/profile/"),
postData为需要提交的数据(
如:L"userid=kesalin&password=pwd&action=profile")
//飘飘白云(l_zhaohui@163.com)2007/11/8
IWebBrowser2* iBrowser;
LPCTSTR url;
LPCTSTR postData;
// .......other codes.
//Get size of Post Data
int size = WideCharToMultiByte(CP_ACP, 0, postData, -1, 0, 0, 0, 0);
VARIANT vURL;
VARIANT vFlags;
VARIANT vPostData;
VARIANT vHeaders;
VARIANT vNull;
// Init
VariantInit(&vURL);
VariantInit(&vFlags);
VariantInit(&vPostData);
VariantInit(&vHeaders);
VariantInit(&vNull);
// Set value
vNull.vt = VT_BSTR;
vNull.bstrVal = NULL;
vHeaders.vt = VT_BSTR;
vHeaders.bstrVal = SysAllocString(L"Content-Type: application/x-www-form-urlencoded\r\n");
vFlags.vt = VT_I4;
vFlags.lVal = navNoReadFromCache | navNoWriteToCache;
vURL.vt = VT_BSTR;
vURL.bstrVal = SysAllocString(url);
if (size > 1) {
// POST
char* pPostData = new char[size + 1];
WideCharToMultiByte(CP_ACP, 0, postData, -1, pPostData, size, 0, 0);
SAFEARRAY FAR* sfPost = NULL;
SAFEARRAYBOUND bound;
bound.cElements = (ULONG) (strlen(pPostData));
bound.lLbound = 0;
sfPost = SafeArrayCreate(VT_UI1, 1, &bound);
char* pChar = pPostData;
for (long lIndex = 0; lIndex < (signed)bound.cElements; lIndex++) {
SafeArrayPutElement(sfPost, &lIndex, (void*)((pChar++)));
}
vPostData.vt = VT_ARRAY | VT_UI1;
vPostData.parray = sfPost;
SafeArrayDestroy(sfPost);
delete[] pPostData;
pPostData = NULL;
pChar = NULL;
iBrowser->Navigate2(&vURL, &vFlags, &vNull, &vPostData, &vHeaders);
}
else {
// GET
iBrowser->Navigate2(&vURL, &vNull, &vNull, &vNull, &vNull);
}
// Clear
VariantClear(&vURL);
VariantClear(&vFlags);
VariantClear(&vPostData);
VariantClear(&vHeaders);
VariantClear(&vNull);
有三点值得说明:第一, 数据类型 VT_I4 是指示一个long型的数据,所以要设置 VARIANT的lVal作为值。如代码中的:
vFlags.vt = VT_I4;
vFlags.lVal = navNoReadFromCache | navNoWriteToCache;
第二, 如果要实现POST数据提交,不能将Navigate2方法中不需要的参数简单地设置成NULL,必须创建一个VARIANT变量vNull,并对它进行初始化。比如:
VariantInit(&vNull);
第三, vPostData的变量类型是VT_ARRAY | VT_UI1,其数据是一个SAFEARRAY型的字符数组,具体赋值请参看代码。
// Set value
vNull.vt = VT_BSTR;
vNull.bstrVal = NULL;
iBrowser->Navigate2(&vURL, &vFlags, &vNull, &vPostData, &vHeaders);




 

使用InternetSetCookie删除cookie

格式为:InternetSetCookie(url,NULL,L"CookieTest=ValTest;path=path value;expires=Thu, 01-Jan-1970 00:00:01 GMT");

使用InternetSetCookie删除cookie ms没有官方文档。经过无数次的测试之后发现:

1。 删除时一定要传入path参数,而且此参数必须和set是一致.
2。 setcookie是不带path参数则是对当前path起作用(如果url是一个文件的话,MS有问题)
3。 不同path值,即使cookie的名字一样也是两个不同的cookie。所以path很重要啊!

用c++ 操作mysql 数据库类

在有大量节点访问的数据库设计中,经常要使用到连接池来管理所有的连接.
一般方法是:建立两个连接句柄队列,空闲的等待使用的队列和正在使用的队列.
当要查询时先从空闲队列中获取一个句柄,插入到正在使用的队列,再用这个句柄做数据库操作,完毕后一定要从使用队列中删除,再插入到空闲队列.

» 阅读全文