前言:
现在大家对“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语句怎么写税收算法