将存储过程输出保存到新表而不重复表类型

时间:2017-12-11 22:18:14

标签: sql stored-procedures hana

我想调用现有过程并将其表类型OUT参数存储到新物理表中,而不必在创建新表时重复输出类型的定义。例如,如果程序是

CREATE PROCEDURE MYPROC
     (IN X INTEGER, OUT Y TABLE(A INTEGER, B DOUBLE, C NVARCHAR(25)))
LANGUAGE SQLSCRIPT AS BEGIN
...
END;

我想为输出创建一个物理表而不重复(A INTEGER, B DOUBLE, C NVARCHAR(25))部分。

如果我已经有了一个表格,我想要我的结果,我可以CREATE TABLE MY_OUTPUT LIKE EXISTING_TABLE,但我没有。

如果我已经为过程的输出类型定义了一个命名类型,我可以根据该类型创建我的表,但我没有。

如果是子查询而不是过程输出参数,我可以CREATE TABLE MY_OUTPUT AS (<subquery>),但它不是子查询,我不知道如何将其表示为子查询。此外,可能有多个输出参数,我不知道你如何使用多个输出参数。

在我的特定情况下,函数来自SAP HANA Predictive Analysis Library,因此我无法更改函数的定义方式。另外,我怀疑PAL对参数类型的异常灵活处理可能会阻止我使用适用于普通SQLScript程序的解决方案,但我仍然对那些适用于常规程序的解决方案感兴趣,即使它们在PAL上失败。

有办法做到这一点吗?

2 个答案:

答案 0 :(得分:0)

据我了解,您希望将数据库表用作输出参数类型。

在我的默认架构中,我有一个名为CITY

的数据库表

我可以使用表作为输出参数类型

,按如下方式创建存储过程
CREATE PROCEDURE MyCityList (
    OUT CITYLIST CITY
)
LANGUAGE SQLSCRIPT 
AS 
BEGIN

CITYLIST = SELECT * FROM CITY;

END;

创建过程后,您可以按如下方式执行

do
begin

declare myList CITY;
call MyCityList(:myList);
select * from :myList;

end;

这是输出数据采用数据库表格式的结果,即CITY表

enter image description here

我希望这能回答你的问题,

  • 首次评论后更新 如果方案与第一个注释中提到的情况相反,则可以查询系统视图PROCEDURE_PARAMETER_COLUMNS并创建将生成包含过程表类型参数中的定义的表的动态SQL语句

这是SQL查询

select 
parameter_name,
'CREATE Column Table ' || 
procedure_name || '_' 
|| parameter_name || ' ( ' || 

string_agg(
    column_name || ' ' || 
    data_type_name || 
    case when data_type_name = 'INTEGER' then '' else
    '(' || length || ')'
    end

    , ',' 
) || ' );'

from PROCEDURE_PARAMETER_COLUMNS 
where 
    schema_name = 'A00077387'
group by procedure_name, parameter_name

您需要根据您的情况替换WHERE子句。 每一行都有这样的输出

CREATE Column Table LISTCITIESBYCOUNTRYID_CITYLIST ( CITYID INTEGER,NAME NVARCHAR(40) );

表名的格式是过程名称和参数名称的连接

最后一点,一些数据类型整数,十进制等需要特殊代码,如排除长度或添加比例等。有些不在此SQL中处理。 我将尽快增强查询并发布更新

答案 1 :(得分:0)

有可能通过使用SQLScript anonymous block来做到这一点:

DO BEGIN
CALL MYPROC(5, Y);
CREATE TABLE BLAH AS (SELECT * FROM :Y);
END;

我们将输出存储到匿名块中的表变量中,然后使用从表变量中获取的数据创建一个物理表。这甚至适用于PAL!不过,打字很多。

我发现的局限性是匿名块的主体不能引用在匿名块之外创建的本地临时表,因此以这种方式将本地临时表传递给过程很尴尬。无论如何,可以通过将本地临时表作为参数传递给匿名块本身来进行此操作,但这需要写出本地临时表的类型,我们试图避免手动编写表类型。