简体   繁体   中英

Using HANA PLACEHOLDER query from java with named parameter replacement

Could someone please explain to me , the difference between using a PLACEHOLDER and a WHERE in sap hana queries. I am new to SAP HANA and in my springboot application , I have to use one PLACEHOLDER query to get some data from a calculated view. The issue is that when using spring data jpa along with SAP HANA , for some reason the PLACEHOLDER query fails to replace the values dynamically during query creation. For instance take the query :

select * from SOME_TABLE ('PLACEHOLDER' = ('$$IP_SOME_COLUMN1$$', 'value1') ,('$$IP_SOME_COLUMN2$$', 'value2'));

whenever we try to dynamically pass values to this query , for some reason the query creation fails . So, we were hoping to use the all so familiar WHERE clause instead , but need clarification on the difference between them and how it might affect performance.

Unlike the WHERE -clause placeholders in HANA are a non-standard/proprietary syntax extension.
The idea is that a query can provide additional information to a view - often that would be filter conditions that otherwise would not be possible to "push-down" in the processing.

These concepts overlap in their use-cases but are completely distinct in their implementation and meaning otherwise.

Concerning the "passing values dynamically" question: the old placeholder syntax does not support SQL query parameters/host variable replacement (the ? in the query text).
To do that, you need to use the new variant of the parameter syntax.

See also How to escape sql injection from HANA placeholder .

The function APPLY_FILTER applies a SQL predicate just like if it was added to the where clause. In the example below the variable sql_filter contains a complex filtering predicate that we want to apply without using dynamic SQL. This is the list of all views created on a Friday:

do begin
  declare sql_filter nvarchar(200) = 'weekday(create_time)=4'; 
  tv= select dayname(create_time) as create_day, schema_name, view_name
  from VIEWS;
  res=APPLY_FILTER(:tv, :sql_filter);
  select * from :res;
end;

This construct with do begin and table variable is not that easy to call from a client application, so I recommend that you write a table function instead:

create or replace function DYN_FILTER_VIEWS(
    IN SQL_FILTER NVARCHAR(1000)
) RETURNS TABLE (
    create_day nvarchar(20), 
    schema_name nvarchar(255),
    view_name nvarchar(255)
)as
begin
  tv= select dayname(create_time) as create_day, schema_name, view_name 
  from VIEWS;
  res=APPLY_FILTER(:tv, :SQL_FILTER);
  return select * from :res;
end;

From the application, you can simply and safely call it by passing a parameter to a prepared statement:

select * from DYN_FILTER_VIEWS('view_name like ''%ELT%'' ')

I'm not an expert, but for hana 2.0 SPS04: I think your syntax is incorrect, you need following syntax for more than one input parameter: -- option 1 - no WITH PARAMETERS clause SELECT "FOO" FROM "_SYS_BIC"."public.FOO_CV"( 'PLACEHOLDER' = ('$$IP2$$','1'), 'PLACEHOLDER' = ('$$IP1$$','2'), 'PLACEHOLDER' = ('$$CE_SUPPORT$$','d_calcengine')); -- option 2 - WITH PARAMETERS clause SELECT "FOO" FROM "_SYS_BIC"."public.FOO_CV" WITH PARAMETERS ( 'PLACEHOLDER' = ('$$IP2$$','1'), 'PLACEHOLDER' = ('$$IP1$$','2'), 'PLACEHOLDER' = ('$$CE_SUPPORT$$','d_calcengine')); -- option 3 - mixed SELECT "FOO" FROM "_SYS_BIC"."public.FOO_CV" WITH PARAMETERS ( 'PLACEHOLDER' = ('$$IP2$$','1'), 'PLACEHOLDER' = ('$$IP1$$','2')) WITH PARAMETERS ('PLACEHOLDER' = ('$$CE_SUPPORT$$','d_calcengine')); -- option 1 - no WITH PARAMETERS clause SELECT "FOO" FROM "_SYS_BIC"."public.FOO_CV"( 'PLACEHOLDER' = ('$$IP2$$','1'), 'PLACEHOLDER' = ('$$IP1$$','2'), 'PLACEHOLDER' = ('$$CE_SUPPORT$$','d_calcengine')); -- option 2 - WITH PARAMETERS clause SELECT "FOO" FROM "_SYS_BIC"."public.FOO_CV" WITH PARAMETERS ( 'PLACEHOLDER' = ('$$IP2$$','1'), 'PLACEHOLDER' = ('$$IP1$$','2'), 'PLACEHOLDER' = ('$$CE_SUPPORT$$','d_calcengine')); -- option 3 - mixed SELECT "FOO" FROM "_SYS_BIC"."public.FOO_CV" WITH PARAMETERS ( 'PLACEHOLDER' = ('$$IP2$$','1'), 'PLACEHOLDER' = ('$$IP1$$','2')) WITH PARAMETERS ('PLACEHOLDER' = ('$$CE_SUPPORT$$','d_calcengine'));

The syntax you used is valid for answering an input parameter which allows for more than one value as an answer.

here, the IP1 and IP2 were created in a calculation view, whereas CE_SUPPORT input parameter is a little bit different - it can be specified for any calculation view (with or without WITH PARAMETERS clause) and is not a part of a definition of a CV.

Regarding the difference between WHERE clause and a PLACEHOLDER syntax, the differences are following:

  1. the syntax is different (dough)

  2. those are two different things - WHERE is used for WHERE clause and PLACEHOLDER is used for passing input parameter answer (dough)

  3. point 2. makes sense only if you know what are input parameters - those are objects that can be used in variety of ways in sap hana. They can give you exact same result as a WHERE clause, but can also be used in other ways like in things called calculated columns, in mapping of input parameters, derived columns i think as well, currency conversion, etc. etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM