如何使用 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为此。此外,您将使用的所有字段在所有对象中都应具有相同的名称,或者应作为参数传递。
但还有一些选择。
- 创建复合提供程序,您将在其中合并需要访问的所有对象,将客户名称和位置映射到输出,为该对象生成外部 HANA 视图并在您的 select 中使用它,但有限制
INFOPROV
维度,而不是动态对象名称。或者不太好,但工作方式 - 使用 HANA 中默认生成的 0BW:BIA:<infoprovname>
列视图来访问相同的数据。
- 复合提供程序的一种变体,但从 ABAP 方面来看:创建 CDS 视图,将所有基数 table 包装成单个
UNION
对象标识符列,编码为 SELECT
相应对象的列表。
- 使用
RSDRI_INFOPROV_READ
功能模块从 ABAP 中所需的信息提供者(动态名称传递)读取该数据,然后将该数据传递给 AMDP。
- 对我来说是最坏的情况,但仅适用于 HANA 2.0,因为在 1.0 中
EXEC
或 EXECUTE IMMEDIATE
中没有添加 INTO
。生成动态SQL,在SQL脚本中使用EXECUTE IMMEDIATE
语句加上INTO
,将其输出的内容抓取到三个变量(客户,位置和日期)然后填充select ... from dummy
: 的表格结果
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.
我一直在尝试解决一个要求,但没有成功,我必须将包含 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为此。此外,您将使用的所有字段在所有对象中都应具有相同的名称,或者应作为参数传递。
但还有一些选择。
- 创建复合提供程序,您将在其中合并需要访问的所有对象,将客户名称和位置映射到输出,为该对象生成外部 HANA 视图并在您的 select 中使用它,但有限制
INFOPROV
维度,而不是动态对象名称。或者不太好,但工作方式 - 使用 HANA 中默认生成的0BW:BIA:<infoprovname>
列视图来访问相同的数据。 - 复合提供程序的一种变体,但从 ABAP 方面来看:创建 CDS 视图,将所有基数 table 包装成单个
UNION
对象标识符列,编码为SELECT
相应对象的列表。 - 使用
RSDRI_INFOPROV_READ
功能模块从 ABAP 中所需的信息提供者(动态名称传递)读取该数据,然后将该数据传递给 AMDP。 - 对我来说是最坏的情况,但仅适用于 HANA 2.0,因为在 1.0 中
EXEC
或EXECUTE IMMEDIATE
中没有添加INTO
。生成动态SQL,在SQL脚本中使用EXECUTE IMMEDIATE
语句加上INTO
,将其输出的内容抓取到三个变量(客户,位置和日期)然后填充select ... from dummy
: 的表格结果
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.