龙空技术网

《循环比对算法一瞥》

良墨 63

前言:

现在大家对“sql语句怎么写税收算法”都比较关切,兄弟们都想要剖析一些“sql语句怎么写税收算法”的相关知识。那么小编同时在网络上汇集了一些对于“sql语句怎么写税收算法””的相关文章,希望你们能喜欢,朋友们一起来了解一下吧!

《循环比对算法一瞥》

良墨经典算法2009年7月13日

在税收征管工作中,有时我们会遇到对存储在不同数据库中的数据进行比对的业务需求,主要目的是找出它们之间的差异性。例如:2005年推行综合征管软件时,为了保证数据的录入质量,就需要对第一次录入的数据与第二次录入的数据进行比对,得到比对结果用以修正数据。笔者把如何思考这个循环比对算法和最终的程序设计做个简要介绍,目的是为大家提供一种算法设计的思路。该算法是一个通用模型可以用于类似的案例,算法本身不依附任何开发工具。为了方便程序说明所采用的是C++ builder 6.0编译环境,分三步进行介绍。

第一步,理清思路明确目标。首先我们要分析在设计这个算法时需要抓住的关键点,便于我在设计时切中要害。关键点一,进行比对的数据库结构完全相同;关键点二,比对涉及的数据表较多,不可能采用静态的列举法,比对的关联字段为纳税人识别号;关键点三,比对的目标是找出两次数据录入的差异性。然后结合关键点进入算法设计的思考阶段,清晰设计思路。由于比对的数据库结构完全相同,那么比对的字段名称也相同,算法上只要一对一的列举比对就可以。另外涉及的数据表较多,采用静态列举法显然是不可行的,我们可以采用软件提供的函数动态提取每张表的数据字段,把它存储到对应的数组。通过关键字段“纳税人识别号”来关联找到比对的记录,实现源记录(第一次录入的数据)和目标记录(第二次录入的数据)的一对一,通过源数组和目标数组的一对一的循环比对,得到比对结果就基本完成了算法的实现。最后再反复斟酌几次,完善思路中的不足,就可以进入第二步算法目标的设计与实现。

第二步,算法目标的设计与实现,根据第一步的思路进行如下算法设计。为了方便说明,只选择了程序的主体进行注解。(注://为程序注释)

1、定义算法中的变量:

public://定义为全局变量

AnsiString CNames[99];//存储数据表中的字段名称的字符串数组变量,存储最大值99个

AnsiString CField[99];//存储源目标表的字段值(第一次录入的数据表)

AnsiString CDField[99];//存储目标表的字段值(第二次录入的数据表)

int i; //用于循环语句中的循环变量,初始值在循环中赋予

int k; //存储比对表中每条记录的字段个数的合计

void SelectTable();//定义一个获取数据记录值的函数,void表示不需要返回值

void SelectCheck();//定义一个进行数据比对的函数

2、算法设计:

2.1动态获取比对数据表的比对字段名称

Main()//程序主体函数

{

ADO1->Close();//ADO1是C++ builder里的一个数据库连接控件,实现获取数据的功能其他开发工具带有类似的控件,ADO1连接的是源数据库中的数据

ADO1->SQL->Clear();//关闭数据库连接,目的清除原来的留存的数据

ADO1->SQL->Text = "select * from "+stablename->Text+" where 1=2";

//"+stablename->Text+"根据用户在控件上输入的内容变量得到要比对的数据表名,select * from 表名 where 1=2 因为1=2不成立,所以数据集得到是表结构而没有具体的任何记录

ADO1->Open();//执行该控件中的SQL语句得到执行结果

k = ADO1->Fields->Count; //ADO控件中属性函数Fields->Count,得到该数据表有多少个字段的个数,目的是在循环赋值中提供一个循环的上限值

for (i=0;i<k;i++)

{

CNames[i] = ADO1->Fields->Fields[i]->FieldName;

// Fields->Fields[i]->FieldName属性,按照顺序取得数据表中的字段名称,并按照相同的顺序赋值到数组CNames[i]中,为下一步取得逐个记录的字段值做好准备

}

SelectTable();//调用获取数据记录的函数,程序会自动跳转到SelectTable()函数去执行

ADO1->Close();

ADO2->Close();//程序执行完毕关闭数据集,释放内存

}

2.2 SelectTable()获取数据记录的函数程序说明:

void SelectTable()

{

ADO1->Close();

ADO1->SQL->Clear();

ADO1->SQL->Text = "select * from "+stablename->Text+" where 1=1";// select * from 表名 where 1=1 因为1=1成立,所以数据集得到是源数据表中的所有数据

ADO1->Open();

ADO1->First();//让数据集中的数据指针指向第一条记录

while (!ADO1->Eof)//如果没有到数据集中的最后一条记录循环将继续执行,否则停止退出

{

for (i=0;i<k;i++)//k是每个记录中所有字段数的合计

{

CField[i] = ADO1->FieldByName(CNames[i])->AsString; //取出字段的数值

}//按照数组CNames[i]存储的顺序,取出源表中第i条记录里的每个字段值,并按照相同的顺序赋值到数组CField[i]中,得到需要比对的每条源记录得每个字段值

SelectCheck();//取得第i条记录的源数值后,执行比对函数

ADO1->Next();//比对一条记录完毕后,指针指向下一条记录继续循环

}

}

2.3 SelectCheck()数据比对函数说明:

void SelectCheck()

{

ADO2->Close();//连接目标数据库数据即第二次录入的数据

ADO2->SQL->Clear();

ADO2->SQL->Text = "select * from "+dtablename->Text+" where 1=1 and nsrsbh = '"+CField[0]+"'";// 根据源数据库中的纳税人识别号值CField[0],通过select * from 目标表 where 1=1 and nsrsbh = “源数据中纳税人识别号值” 得到对应的需要比对的目标记录值

ADO2->Open();

if (ADO2->RecordCount != 0)//如果取得需要比对的目标数据值,则执行if语句

{

for (i=0;i<k;i++)//因为数据结构相同,所以与源数据取数相同

{

CDField[i] = ADO2->FieldByName(CNames[i])->AsString;

}//因为源数据表和目标数据表中的数据结构相同,所以用相同的k取得目标表中与源表中对应的记录的每个字段值

//进行源数据和目标数据的对应记录的字段值进行比对

for (i=1;i<k;i++)//循环比对对应记录中的所有字段值

{

if(CField[i] == CDField[i])//因为源和目标数组存储的位置相同,所以进行对应位置的数组值比对,如果对应字段相同则执行if,否则执行else

{

exit;//退出

}

else

{

//省略保存比对不符的记录语句

}

}//进行数据比对

}//if结束标志

}

以上主体程序基本完成了循环比对算法的程序实现,下一步进入算法测试运行及小结。

第三步,算法测试运行及小结,以上的算法通过实际运用收到了较好的效果。对于算法设计我个人认为,主要是思路决定算法,不要拘泥于某种开发工具和平台,最主要的是如何通过思考来解决问题。本篇文章有不足之处请大家多多指正批评。

标签: #sql语句怎么写税收算法