Использование запроса HANA PLACEHOLDER из java с заменой именованного параметра - PullRequest
0 голосов
/ 27 января 2020

Может, кто-нибудь объяснит мне разницу между использованием PLACEHOLDER и WHERE в запросах sap hana. Я новичок в SAP HANA, и в моем приложении Springboot мне нужно использовать один запрос PLACEHOLDER, чтобы получить некоторые данные из вычисленного представления. Проблема заключается в том, что при использовании пружинных данных jpa вместе с SAP HANA по какой-то причине в запросе PLACEHOLDER не удается динамически заменить значения во время создания запроса. Например, возьмите запрос:

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

всякий раз, когда мы пытаемся динамически передать значения в этот запрос, по какой-то причине создание запроса завершается неудачно. Таким образом, мы надеялись использовать взамен столь знакомое предложение WHERE, но нам нужно уточнить разницу между ними и то, как это может повлиять на производительность.

Ответы [ 3 ]

1 голос
/ 30 января 2020

В отличие от WHERE -заполнителей в HANA это нестандартное / проприетарное расширение синтаксиса.
Идея состоит в том, что запрос может предоставить дополнительную информацию для представления - часто это были бы условия фильтрации, которые в противном случае не возможно "pu sh -down" в обработке.

Эти концепции частично совпадают в их вариантах использования, но совершенно различны в своей реализации и имеют другое значение.

Относительно "передачи" значения динамически "вопрос: старый синтаксис заполнителя не поддерживает SQL параметры запроса / замена переменных хоста (символ? в тексте запроса).
Для этого вам нужно использовать новый вариант синтаксиса параметра.

См. Также Как избежать sql инъекции из заполнителя HANA .

0 голосов
/ 23 апреля 2020

Я не эксперт, но для hana 2.0 SPS04: Я думаю, что ваш синтаксис неправильный, вам нужен следующий синтаксис для более чем одного входного параметра: -- 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'));

Используемый вами синтаксис действителен для ответ на входной параметр, который допускает более одного значения в качестве ответа.

здесь IP1 и IP2 были созданы в виде вычисления, тогда как входной параметр CE_SUPPORT немного отличается - его можно указать для любого представление расчета (с предложением WITH PARAMETERS или без него) и не является частью определения CV.

Что касается различия между предложением WHERE и синтаксисом PLACEHOLDER, различия следующие:

  1. синтаксис другой (тест)

  2. это две разные вещи - WHERE используется для предложения WHERE и PLACEHOLDER используется для передачи ответа входного параметра (тесто)

  3. пункт 2. имеет смысл, только если вы знаете, что такое входные параметры - это объекты, которые можно использовать в различных путей в Сап хана. Они могут дать вам тот же результат, что и предложение WHERE, но также могут использоваться и другими способами, например, в так называемых вычисляемых столбцах, в отображении входных параметров, производных столбцах, которые, я думаю, также и в конвертации валют и т. Д. c. и др c.

0 голосов
/ 21 февраля 2020

Функция APPLY_FILTER применяет предикат SQL точно так же, как если бы он был добавлен в предложение where. В приведенном ниже примере переменная sql_filter содержит сложный предикат фильтрации, который мы хотим применить без использования dynamici c SQL. Это список всех представлений, созданных в пятницу:

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;

Эта конструкция с do begin и табличной переменной не так просто вызвать из клиентского приложения, поэтому я рекомендую вместо этого написать табличную функцию :

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;

Из приложения вы можете просто и безопасно вызвать его, передав параметр в подготовленный оператор:

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