如何使用 HANA 存储过程的输入参数中的字段为 execute_immediate 语句动态生成 table 名称?

How to use a field from an input parameter of a HANA stored procedure to generate table name dynamically for execute_immediate statement?

我一直在尝试解决一个要求,但没有成功,我必须将包含 3 个字段的 table 传递给存储过程:对象名称、客户和位置,从 AMDP 到存储过程。存储过程应该用于 return 存储相同客户、位置和最小(日期)的 table。

最小值(日期)在 table 中找到,该 table 派生自对象名称,如下所示:'"/BIC/A' || (object name passed from AMDP) || 2"' 的串联。所以,假设 AMDP 将参数对象作为 YCUSTM01 传递,那么查找最小日期的 table 名称应该是 "/BIC/AYCUSTM012"。因此,我应该能够做出 execute_immediate 声明(也许?)以找到客户在特定位置的最短日期是什么 & return table 返回 AMDP 进一步计算。

输入Table:

| Object_name | Customer | Location |
+-------------+----------+----------+
| YCUSTM01    | Walgreen | Chicago  |

"/BIC/AYCUSTM012"中的示例数据:

| Customer | Location | Date       |
+----------+----------+------------+
| Walgreen | Chicago  | 24.09.2020 |
| Walgreen | Chicago  | 07.02.2019 |
| Walgreen | Chicago  | 12.12.2012 |
| Walgreen | Chicago  | 01.04.2015 |

存储过程的期望输出Table:

  select
    customer,
    location,
    min(calday)
  from "/BIC/AYCUSTM012"
  where customer = :customer
    and location = :location
  group by
    customer,
    location;

  | Customer | Location | Min_date   |
  +----------+----------+------------+
  | Walgreen | Chicago  | 12.12.2012 |

如有任何线索,我们将不胜感激。

动态对象名有很多缺点。

  • 它违反了 SAP BW 的所有安全性。
  • 它不跟踪对象引用,因此您无法在 ABAP 或 HANA(通过 OBJECT_DEPENDENCIES 视图)中获取 ADSO 的使用位置列表。
  • 它在对象替换方面没有灵活性:想象一下,有一天你需要使用 Composite Provider 或 infoobject 主数据 table 来查看。在 HANA 端你无法轻松获取基础table为此。此外,您将使用的所有字段在所有对象中都应具有相同的名称,或者应作为参数传递。

但还有一些选择。

  1. 创建复合提供程序,您将在其中合并需要访问的所有对象,将客户名称和位置映射到输出,为该对象生成外部 HANA 视图并在您的 select 中使用它,但有限制INFOPROV 维度,而不是动态对象名称。或者不太好,但工作方式 - 使用 HANA 中默认生成的 0BW:BIA:<infoprovname> 列视图来访问相同的数据。
  2. 复合提供程序的一种变体,但从 ABAP 方面来看:创建 CDS 视图,将所有基数 table 包装成单个 UNION 对象标识符列,编码为 SELECT相应对象的列表。
  3. 使用 RSDRI_INFOPROV_READ 功能模块从 ABAP 中所需的信息提供者(动态名称传递)读取该数据,然后将该数据传递给 AMDP。
  4. 对我来说是最坏的情况,但仅适用于 HANA 2.0,因为在 1.0 中 EXECEXECUTE IMMEDIATE 中没有添加 INTO。生成动态SQL,在SQL脚本中使用EXECUTE IMMEDIATE语句加上INTO,将其输出的内容抓取到三个变量(客户,位置和日期)然后填充select ... from dummy:
  5. 的表格结果
execute immediate 'select customer, location, min(date)
from <dyn_tab_name>
where customer = ''' || :p_cust || '''
  and location = ''' || :p_loc || '''
group by customer, location'
  into lv_cust, lv_loc, lv_date;

outTab =
  select :lv_cust as customer
    :lv_loc as location,
    :lv_date as min_date
  from dummy;

我没有 HANA 2.0 DBMS 来检查如何将绑定变量与 USING 一起用于传递给 EXEC 的参数而不是简单的连接,并且文档中没有相关示例。希望 Lars 将添加有关该功能的一些信息。

关于该动态代码还有一点:如果可以,传递多个客户和位置进行检索,因为对于 HANA 中的单行处理,解析所花费的时间几乎与数据相同(或者可能多出数倍)检索过程。因此 select 来自多个客户的联合数据会表现更好:

astentx 非常正确:直接在您的代码中访问 SAP BW ADSO tables 并不是最好的主意。相反,建议使用这些 ADSO 对象的外部视图

但这不是动态 SQL 方法的主要问题。同样,astentx 已经全面概述了为什么使用动态 SQL 不是一个好主意,因此我不再重复。

我推荐的解决方法需要更多步骤,并导致数据选择和数据计算的代码分离。processing/query。

这里描述了包括演示在内的完整方法:The Lars Breddemann Blog: Separate business logic from tables and avoid dynamic SQL,所以这里是它的粗略大纲:

  • 创建一个 table 函数,在适当的 table 类型 而不是特定的 table[=31 上执行您想要的计算=]
  • 对于每个要使用逻辑的 table,创建样板代码,从 table 和 转换选择 它匹配 table 类型 的 table 函数
  • 现在只有样板代码依赖于物理 table(你无论如何都必须拥有的东西,因为你需要在某处输入 table 的参数)和 computation/business逻辑独立于任何物理tables.