我需要将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;
提前致谢。
答案 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中)的数据。
通常的要求是能够从“更高”的位置执行某些操作,访问任何这些客户端模式中的数据。 这就是您的要求似乎发挥作用的地方。
这种方法存在一些问题:
另一种方法可能是在这种情况下反转设计。 不是在X表上创建动态视图(每个模式一个),而是为模式中的通用表创建模式,并在每个模式中创建过滤视图。
这样,“主”模式可以轻松访问共享表而无需任何动态SQL,因为“客户端”模式可以以视图的形式访问表的“他们的”版本。
在INSTEAD OF
触发器的帮助下,可以轻松地针对视图重定向INSERT
/ UPDATE
语句,以便适当添加过滤条件。
这种方法,就像动态SQL方法一样,省去了应该运行过程的实际客户端应用程序的选项,以使用SET SCHEMA <schema name>
命令动态切换到感兴趣的模式。
虽然SET SCHEMA
对过程没有帮助(在编译时静态检查对象引用,但还记得吗?)在客户端应用程序中很容易发出命令并将SELECT COUNT(*)
的结果反馈给处理进一步业务逻辑的过程。