本发明涉及数据库技术领域,尤其涉及一种用于opengauss数据库的解析动态sql的方法及系统。
背景技术:
动态sql的执行是大部分数据库系统中都支持的特性。基本的形式是在sql语句中使用占位符取代变量,到实际执行时再将变量赋给占位符,从而执行最终的sql语句,并返回最后的结果集。一般来讲需要使用动态sql的部分都是在编写程序时无法确定最终参数的取值,需要在运行时临时指定参数值。与静态sql相比,动态sql在执行效率上一般不及静态sql,但是灵活度上要优于静态sql。
oracle中存在一个解析动态sql的框架dbms_sql,该框架弥补了本地动态sql只能实现固定数量的输入输出变量,且每执行一次都打开和关闭游标一次的缺点,可以实现不定数量的输入和不定数量的输出,一次打开游标可多次使用,在执行效率上要优于本地动态sql。
目前在opengauss数据库中没有解析动态sql的功能,如何在数据库实现一个兼容dbms_sql的动态sql解析框架,以实现oracle中dbms_sql包中的大部分操作,实现不定数量的输入和不定数量的输出,成为亟待解决的技术问题。
技术实现要素:
有鉴于此,本发明提供一种用于opengauss数据库的解析动态sql的方法及系统,以实现在opengauss数据库中解析动态sql。
一方面,本发明提供一种用于opengauss数据库的解析动态sql的方法,包括:声明一个全局性数据结构用于存储游标的数据,初始化所述全局性数据结构中的变量;
将待执行的sql语句保存到所述全局性数据结构的querybuf字段,根据所述sql语句构建可执行语句;
调用opengauss数据库中的软件开发接口执行所述可执行语句。
进一步地,所述根据所述sql语句构建prepare语句的步骤包括:
根据querybuf保存的语句,构建prepare语句;
调用opengauss数据库中的软件开发接口对所述prepare语句进行语法分析;
根据语法分析结果判断是否需要绑定变量;
若确定需要绑定变量,则将prepare语句的参数绑定变量,得到可执行语句,并基于所述可执行语句更新所述全局性数据结构的querybuf字段;
若确定不需要绑定变量,则将prepare语句作为可执行语句。
进一步地,在所述根据所述sql语句构建可执行语句的步骤之后包括:
判断是否需要反馈可执行语句的执行结果;
在确定需要反馈执行结果时,定义用于接收可执行语句的执行结果的结果列;
在所述调用opengauss数据库中的软件开发接口执行所述可执行语句的步骤之后包括:
将所述全局性数据结构中tup_list存储的可执行语句的执行结果取出,并将执行结果保存至所述结果列,之后关闭游标。
进一步地,在判断是否需要反馈可执行语句的执行结果的步骤之后包括:
在确定不需要反馈执行结果时,直接执行所述调用opengauss数据库中的软件开发接口执行所述可执行语句,之后关闭游标。
进一步地,所述全局性数据结构包括:用于表示游标的编号的id字段、用于表示结果集的总行数的all_rows字段、用于表示取出结果行数的fetched_rows字段、用于表示结果列的位置索引的colno字段、用于表示结果集缓存的tup_list字段、用于表示结果集描述符的tupdesc字段、用于表示下一个游标的指针的next字段、以及用于表示执行sql原文的querybuf字段。
另一方面,本发明还提供一种用于opengauss数据库的解析动态sql的系统,包括:
数据结构声明单元,用于声明一个全局性数据结构用于存储游标的数据,初始化所述全局性数据结构中的变量;
语句构建单元,用于将待执行的sql语句保存到所述全局性数据结构的querybuf字段,根据所述sql语句构建可执行语句;
语句执行单元,用于调用opengauss数据库中的软件开发接口执行所述可执行语句。
进一步地,所述语句构建单元包括:
构建子单元,用于根据querybuf保存的语句,构建prepare语句;
分析子单元,用于调用opengauss数据库中的软件开发接口对所述prepare语句进行语法分析;
判断子单元,用于根据语法分析结果判断是否需要绑定变量;若确定需要绑定变量,则将prepare语句的参数绑定变量,得到可执行语句,并基于所述可执行语句更新所述全局性数据结构的querybuf字段;若确定不需要绑定变量,则将prepare语句作为可执行语句。
进一步地,所述语句执行单元具体用于:判断是否需要反馈可执行语句的执行结果;在确定需要反馈执行结果时,定义用于接收可执行语句的执行结果的结果列;在所述调用opengauss数据库中的软件开发接口执行所述可执行语句的步骤之后包括:将所述全局性数据结构中tup_list存储的可执行语句的执行结果取出,并将执行结果保存至所述结果列,之后关闭游标。
进一步地,所述语句执行单元还用于:在确定不需要反馈执行结果时,直接执行所述调用opengauss数据库中的软件开发接口执行所述可执行语句,之后关闭游标。
进一步地,所述全局性数据结构包括:用于表示游标的编号的id字段、用于表示结果集的总行数的all_rows字段、用于表示取出结果行数的fetched_rows字段、用于表示结果列的位置索引的colno字段、用于表示结果集缓存的tup_list字段、用于表示结果集描述符的tupdesc字段、用于表示下一个游标的指针的next字段、以及用于表示执行sql原文的querybuf字段。
本发明用于opengauss数据库的解析动态sql的方法及系统,能在opengauss数据库中解析动态sql,在执行效率上要明显优于本地动态sql的执行过程,并且能够保证动态sql的灵活度。
附图说明
为了更清楚地说明本发明实施例的技术方案,下面将对实施例中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其它的附图。
图1为根据本发明示例性第一实施例的用于opengauss数据库的解析动态sql的方法的流程图。
图2为根据本发明示例性第二实施例的用于opengauss数据库的解析动态sql的方法的流程图。
图3为根据本发明示例性第三实施例的用于opengauss数据库的解析动态sql的系统的结构框图。
具体实施方式
下面结合附图对本发明实施例进行详细描述。
需说明的是,在不冲突的情况下,以下实施例及实施例中的特征可以相互组合;并且,基于本公开中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本公开保护的范围。
需要说明的是,下文描述在所附权利要求书的范围内的实施例的各种方面。应显而易见,本文中所描述的方面可体现于广泛多种形式中,且本文中所描述的任何特定结构及/或功能仅为说明性的。基于本公开,所属领域的技术人员应了解,本文中所描述的一个方面可与任何其它方面独立地实施,且可以各种方式组合这些方面中的两者或两者以上。举例来说,可使用本文中所阐述的任何数目个方面来实施设备及/或实践方法。另外,可使用除了本文中所阐述的方面中的一或多者之外的其它结构及/或功能性实施此设备及/或实践此方法。
图1为根据本发明示例性第一实施例的用于opengauss数据库的解析动态sql的方法的流程图,如图1所示,本发明一种用于opengauss数据库的解析动态sql的方法,包括:
步骤101:声明一个全局性数据结构用于存储游标的数据,初始化所述全局性数据结构中的变量;
步骤102:将待执行的sql语句保存到所述全局性数据结构的querybuf字段,根据所述sql语句构建可执行语句;
步骤103:调用opengauss数据库中的软件开发接口(softwareprogramminginterface,后文简称spi)执行所述可执行语句。通过使用opengauss平台中提供的软件开发接口(softwareprogramminginterface,后文简称spi)来实现相关的功能,采用非侵入式的开发方法。使用该方法的好处在于可以避免对数据库的内核进行修改,一方面防止对数据库的其他特性产生影响,另一方面也可以防止对数据库的稳定性造成影响。
本实施例用于opengauss数据库的解析动态sql的方法,能在opengauss数据库中解析动态sql,在执行效率上要明显优于本地动态sql的执行过程,并且能够保证动态sql的灵活度。尤其是对于需要传入多次不同参数的应用场景,其效率的提升更加明显。同时,该解析动态sql的方法可以完全兼容oracle中的dbms_sql包的功能,为oracle应用程序迁移到opengauss平台提供了重要的功能支持。
图2为根据本发明示例性第二实施例的用于opengauss数据库的解析动态sql的方法的流程图,图2为图1所示实施例的优选实施方式。本实施例用于opengauss数据库的解析动态sql的方法兼容oracle的dbms_sql动态sql包,所以其执行过程与函数功能也参照oracle的dbms_sql包的流程进行组织。具体如图2所示,本发明一种用于opengauss数据库的解析动态sql的方法,包括:
1、通过函数open_cursor打开游标,具体为:声明一个全局性数据结构用于存储游标的相关数据,在该函数中初始化成员变量,并分配游标的索引,然后返回该索引。
具体地,本实施例动态sql解析框架与本地动态sql语句相比执行效率上要更加高效,通过自定义游标结构,而不是复用opengauss平台中原有的游标结构,以便执行过程更加灵活和高效。游标数据结构定义如下:
其中:id表示游标的编号
all_rows表示结果集的总行数
fetched_rows表示fetch的结果行数
colno表示结果列的位置索引
tup_list表示结果集缓存
tupdesc表示结果集描述符
next表示下一个游标的指针
querybuf表示执行的sql原文。
2、通过parse函数进行语法分析:将执行的sql语句保存到querybuf字段,以querybuf保存的语句为素材,构建prepare语句,并使用spi的接口进行该prepare语句的语法分析。
3、根据语法分析结果判断是否需要绑定变量?此步骤是指在要执行的sql语句中,是否需要绑定变量,因为是动态sql,所以可能sql语句中会需要传参数,可以把变量理解为sql语句中的参数。
4、在确定需要绑定变量时,通过bind_variable函数绑定变量,具体包括将绑定的变量与prepare中的参数相对应,整理成格式化的可执行语句,并替换querybuf语句。
5、判断可执行语句是否需要返回结果?
6、在确定不需要返回结果时,通过execute函数执行querybuf保存的可执行语句,将结果集保存到tup_list中,之后执行步骤11。
7、在确定需要返回结果时,通过define_column函数定义结果列。因为游标中的结果是不可见的,需要把游标中的结果保存在外部的一个变量里,才可以在后续步骤使用,定义结果列就是定义一个接收游标中结果的变量。
8、通过execute函数执行querybuf保存的可执行语句,将结果集保存到tup_list中。
9、通过fetch_rows取出结果,具体包括:返回tup_list中的一行结果,并修改fetched_rows字段,用于记录当前结果在结果集中的相对位置(或者说一共fetch的行数)。
10、通过column_value以及variable_value保存结果,具体地通过variable_value返回结果集字段tup_list,通过column_value函数将fetch的结果按列拆分,将结果返回给对应的参数。
11、通过close_cursor关闭游标,具体包括:清理cursor中的内存,并删除对应的cursor
本实施例通过对以上关键数据结构的定义和使用spi接口实现上述函数功能,即可构建出兼容oracle中dbms_sql包的动态sql解析框架。该框架使用spi的接口仅执行一次sql语句,而后将结果集保存到缓存中,后续的操作均通过操作缓存中的数据来模拟游标的相关操作,在执行效率上要明显优于需要多次开关游标操作的本地动态sql的执行过程。
图3为根据本发明示例性第三实施例的用于opengauss数据库的解析动态sql的系统的结构框图。如图3所示,用于opengauss数据库的解析动态sql的系统包括:
数据结构声明单元301,用于声明一个全局性数据结构用于存储游标的数据,初始化所述全局性数据结构中的变量;
语句构建单元302,用于将待执行的sql语句保存到所述全局性数据结构的querybuf字段,根据所述sql语句构建可执行语句;
语句执行单元303,用于调用opengauss数据库中的软件开发接口执行所述可执行语句。
优选地,所述语句构建单元302包括:
构建子单元(图中未示出),用于根据querybuf保存的语句,构建prepare语句;
分析子单元(图中未示出),用于调用opengauss数据库中的软件开发接口对所述prepare语句进行语法分析;
判断子单元(图中未示出),用于根据语法分析结果判断是否需要绑定变量;若确定需要绑定变量,则将prepare语句的参数绑定变量,得到可执行语句,并基于所述可执行语句更新所述全局性数据结构的querybuf字段;若确定不需要绑定变量,则将prepare语句作为可执行语句。
优选地,所述语句执行单元303具体用于:判断是否需要反馈可执行语句的执行结果;在确定需要反馈执行结果时,定义用于接收可执行语句的执行结果的结果列;在所述调用opengauss数据库中的软件开发接口执行所述可执行语句的步骤之后包括:将所述全局性数据结构中tup_list存储的可执行语句的执行结果取出,并将执行结果保存至所述结果列,之后关闭游标。
进一步优选地,所述语句执行单元303还用于:在确定不需要反馈执行结果时,直接执行所述调用opengauss数据库中的软件开发接口执行所述可执行语句,之后关闭游标。
具体操作时,所述全局性数据结构包括:用于表示游标的编号的id字段、用于表示结果集的总行数的all_rows字段、用于表示取出结果行数的fetched_rows字段、用于表示结果列的位置索引的colno字段、用于表示结果集缓存的tup_list字段、用于表示结果集描述符的tupdesc字段、用于表示下一个游标的指针的next字段、以及用于表示执行sql原文的querybuf字段。
本实施例在opengauss平台下的动态sql解析框架,通过该框架的实现能够在保证动态sql灵活度的基础上,实现动态sql执行效率上的提升,并且能够兼容oracle平台下的dbms_sql包的特性。
以上所述,仅为本发明的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到的变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应以权利要求的保护范围为准。
1.一种用于opengauss数据库的解析动态sql的方法,其特征在于,包括:
声明一个全局性数据结构用于存储游标的数据,初始化所述全局性数据结构中的变量;
将待执行的sql语句保存到所述全局性数据结构的querybuf字段,根据所述sql语句构建可执行语句;
调用opengauss数据库中的软件开发接口执行所述可执行语句。
2.根据权利要求1所述的用于opengauss数据库的解析动态sql的方法,其特征在于,所述根据所述sql语句构建prepare语句的步骤包括:
根据querybuf保存的语句,构建prepare语句;
调用opengauss数据库中的软件开发接口对所述prepare语句进行语法分析;
根据语法分析结果判断是否需要绑定变量;
若确定需要绑定变量,则将prepare语句的参数绑定变量,得到可执行语句,并基于所述可执行语句更新所述全局性数据结构的querybuf字段;
若确定不需要绑定变量,则将prepare语句作为可执行语句。
3.根据权利要求2所述的用于opengauss数据库的解析动态sql的方法,其特征在于,在所述根据所述sql语句构建可执行语句的步骤之后包括:
判断是否需要反馈可执行语句的执行结果;
在确定需要反馈执行结果时,定义用于接收可执行语句的执行结果的结果列;
在所述调用opengauss数据库中的软件开发接口执行所述可执行语句的步骤之后包括:
将所述全局性数据结构中tup_list存储的可执行语句的执行结果取出,并将执行结果保存至所述结果列,之后关闭游标。
4.根据权利要求3所述的用于opengauss数据库的解析动态sql的方法,其特征在于,在判断是否需要反馈可执行语句的执行结果的步骤之后包括:
在确定不需要反馈执行结果时,直接执行所述调用opengauss数据库中的软件开发接口执行所述可执行语句,之后关闭游标。
5.根据权利要求1-4中任一项所述的用于opengauss数据库的解析动态sql的方法,其特征在于,所述全局性数据结构包括:用于表示游标的编号的id字段、用于表示结果集的总行数的all_rows字段、用于表示取出结果行数的fetched_rows字段、用于表示结果列的位置索引的colno字段、用于表示结果集缓存的tup_list字段、用于表示结果集描述符的tupdesc字段、用于表示下一个游标的指针的next字段、以及用于表示执行sql原文的querybuf字段。
6.一种用于opengauss数据库的解析动态sql的系统,其特征在于,包括:
数据结构声明单元,用于声明一个全局性数据结构用于存储游标的数据,初始化所述全局性数据结构中的变量;
语句构建单元,用于将待执行的sql语句保存到所述全局性数据结构的querybuf字段,根据所述sql语句构建可执行语句;
语句执行单元,用于调用opengauss数据库中的软件开发接口执行所述可执行语句。
7.根据权利要求6所述的用于opengauss数据库的解析动态sql的系统,其特征在于,所述语句构建单元包括:
构建子单元,用于根据querybuf保存的语句,构建prepare语句;
分析子单元,用于调用opengauss数据库中的软件开发接口对所述prepare语句进行语法分析;
判断子单元,用于根据语法分析结果判断是否需要绑定变量;若确定需要绑定变量,则将prepare语句的参数绑定变量,得到可执行语句,并基于所述可执行语句更新所述全局性数据结构的querybuf字段;若确定不需要绑定变量,则将prepare语句作为可执行语句。
8.根据权利要求7所述的用于opengauss数据库的解析动态sql的系统,其特征在于,所述语句执行单元具体用于:判断是否需要反馈可执行语句的执行结果;在确定需要反馈执行结果时,定义用于接收可执行语句的执行结果的结果列;在所述调用opengauss数据库中的软件开发接口执行所述可执行语句的步骤之后包括:将所述全局性数据结构中tup_list存储的可执行语句的执行结果取出,并将执行结果保存至所述结果列,之后关闭游标。
9.根据权利要求8所述的用于opengauss数据库的解析动态sql的系统,其特征在于,所述语句执行单元还用于:在确定不需要反馈执行结果时,直接执行所述调用opengauss数据库中的软件开发接口执行所述可执行语句,之后关闭游标。
10.根据权利要求6-9中任一项所述的用于opengauss数据库的解析动态sql的系统,其特征在于,所述全局性数据结构包括:用于表示游标的编号的id字段、用于表示结果集的总行数的all_rows字段、用于表示取出结果行数的fetched_rows字段、用于表示结果列的位置索引的colno字段、用于表示结果集缓存的tup_list字段、用于表示结果集描述符的tupdesc字段、用于表示下一个游标的指针的next字段、以及用于表示执行sql原文的querybuf字段。
技术总结