在动态查询中将count(*)值存入sap hana过程中的变量

时间:2017-11-17 17:32:17

标签: hana

我需要将count(*)值存储到变量中,然后将此变量用于业务逻辑。我已编写下面的代码,但它不起作用。我们要求通过输入参数传递模式名称,因此在过程中使用动态查询。

代码:

Begin

DECLARE v_count INT DEFAULT 0;
DECLARE v_Count_Query NVARCHAR(5000);

CREATE GLOBAL TEMPORARY TABLE RECORD_CNT_TABLE(RECORDS_CNT INTEGER);

v_Count_Query = 'INSERT INTO RECORD_CNT_TABLE(SELECT COUNT(*) FROM "'||:IP_Schema_Name||'"."TABLE_NAME" where to_dats(to_char("LastRunDay", ''yyyymmdd'')) = '||current_date||';';

EXECUTE IMMEDIATE :v_Count_Query; 

EXECUTE IMMEDIATE 'SELECT RECORDS_CNT INTO '||v_count||' FROM RECORD_CNT_TABLE;';

IF :v_count >= 1 then
/**business logic**/
ELSE
/**business logic**/
END IF;  

END;

提前致谢。

1 个答案:

答案 0 :(得分:0)

以下适用于HANA2但不适用于HANA1。

create or replace procedure check_and_do_clients (IN schema_name Nvarchar(256))
as 
begin

DECLARE v_count INT := 0;   

    exec 'select count(*) from "' || :schema_name || '"."APPL_DATA"'
         ||' where "LastRunDay" = date''01.06.2017'' ' into v_count ;

    IF :v_count >= 1 then
              select 'WE HAVE A WINNER!', :v_count as vcnt, :schema_name as schema_name from dummy;
    ELSE
             select 'NO LUCK THIS TIME!', :v_count as vcnt, :schema_name as schema_name from dummy;
    END IF;  

end;
  

'我们有一个胜利者!' VCNT SCHEMA_NAME
     我们有一个胜利者! 1 CLNT1

这里真的不需要临时表。即使您计划重用当前事务范围之外的值,创建 全局临时表也不应该在运行时发生。 创建一次并使用TRUNCATE TABLE清空它,然后再使用它。无论如何,只要您的会话处于活动状态并且仅对创建它的会话可见,数据才会存在。

与此相关的更多是您编写此过程的应用程序的更广泛设计。 SQL中的模式是名称空间,而SQL是静态类型的,表"CLNT1"."APPL_DATA""CLNT2"."APPL_DATA"不同,这当然是为什么必须在此设置中使用动态SQL的原因。

通常,当我遇到这样的设计时,模式概念被用于更多的东西,特别是在不同的命名空间中具有相同模式的结构相同的副本。目标是在同一数据库中分离来自不同租户客户端(在经典SAP中)的数据。

通常的要求是能够从“更高”的位置执行某些操作,访问任何这些客户端模式中的数据。 这就是您的要求似乎发挥作用的地方。

这种方法存在一些问题:

  • 动态SQL通常会占用大量资源并且容易出现SQL注入
  • 它 - 如所见 - 更难编写,只在运行时被数据库检查
  • 数据访问模式通过未包含在架构中的代码打开直接数据访问来打破自包含客户端 -schema的模型

另一种方法可能是在这种情况下反转设计。 不是在X表上创建动态视图(每个模式一个),而是为模式中的通用表创建模式,并在每个模式中创建过滤视图。

这样,“主”模式可以轻松访问共享表而无需任何动态SQL,因为“客户端”模式可以以视图的形式访问表的“他们的”版本。 在INSTEAD OF触发器的帮助下,可以轻松地针对视图重定向INSERT / UPDATE语句,以便适当添加过滤条件。

这种方法,就像动态SQL方法一样,省去了应该运行过程的实际客户端应用程序的选项,以使用SET SCHEMA <schema name>命令动态切换到感兴趣的模式。 虽然SET SCHEMA对过程没有帮助(在编译时静态检查对象引用,但还记得吗?)在客户端应用程序中很容易发出命令并将SELECT COUNT(*)的结果反馈给处理进一步业务逻辑的过程。