Jonas M.
Jonas M.

Reputation: 13

Using WITH Statement in SAP HANA table functions

Is it possible to use the WITH statement in SAP HANA table functions or is there any alternative that I can use within table functions?

CREATE OR REPLACE FUNCTION "MY_SCHEMA"."TF_TEST_1" ()
RETURNS TABLE ( 
mytext NVARCHAR(200)

) LANGUAGE SQLSCRIPT SQL SECURITY INVOKER AS
BEGIN RETURN

WITH X AS (SELECT 'asdf' AS mytext FROM dummy)
SELECT * FROM X;

END;

Upvotes: 0

Views: 2613

Answers (1)

astentx
astentx

Reputation: 6751

In table function you need to explicitly return a table with return statement. As experiment showed, with is not allowed inside return (similar to CTAS: create table from select statement starting with with throws an error).

But you can assign the result of your statement to table variable and return it.

create function test_tf (x int)
returns table (
  id int
)
as begin

  res = with a as (
    select x as id
    from dummy
  )
  select *
  from a;

  return(:res);
end;

select *
from test_tf(1);


|   | ID|
|--:|--:|
|  1|  1|

But in HANA SQLScript we prefer to use table variables instead ow with statements, because they allow step-by-step debugging of the code with no need to rewrite it or run externally as SQL statement with prepared input and select placed after each with. You can declare them on-the-fly, that allows you not to declare something strange upfront. So the way to rewrite it is:

alter function test_tf (x int)
returns table (
  id int
)
as begin

  /*with a as */
  a =
    select x as id
    from dummy
  ;
  
  res = 
    select *
    from :a;

  return(:res);
end;

Note: the only thing is to add a colon before table variable when you access it so parser can distinguish it from table name.

If you want to debug your code before publishing as a function, just replace create function statement with do and return with select * from <return variable>. To view intermediary results you still need to place select * from :table_var somewhere inbetween, because as far as I know anonymous block doesn't allow debuggind with debugger.

do (in x int => ?)
begin

  /*with a as */
  a =
    select x as id
    from dummy
  ;
  
  res = 
    select *
    from :a;

  select * from :res;
  --return(:res);
end;

Upvotes: 1

Related Questions