Невозможно создать пользователей в базе данных Hana с помощью execBatch ()

#sql #node.js #hana #sap-cloud-platform

#sql #node.js #hana #sap-облачная платформа

Вопрос:

У меня есть система XSA и пользователь базы данных XSA. Этот пользователь XSA DB будет использоваться для создания новых пользователей базы данных Hana в XSA. Я пытаюсь создать группу пользователей с помощью функции execBatch (). У меня есть ограничение с node.js проект.

Я выполняю sql-запросы в своем node.js досье. Ниже приведен код-

 console.log("Targeting User Creation")
try{
       let createuserstatement = await xsaDbConn.preparePromisified("CREATE USER ? PASSWORD AbcYes NO FORCE_FIRST_PASSWORD_CHANGE")
       await createuserstatement.execBatch(createusersarr)
       console.log(`Users created.`) 
}catch(err){
       console.log(err.stack)
}
  

createusersarr — это массив, содержащий список создаваемых пользователей. Массив выглядит следующим образом —

 [ [ 'SAC_XSA_HDB_USER_ABC1' ], [ 'SAC_XSA_HDB_USER_ABC2' ], 
  [ 'SAC_XSA_HDB_USER_ABC3' ], [ 'SAC_XSA_HDB_USER_ABC4' ], 
  [ 'SAC_XSA_HDB_USER_ABC5' ], [ 'SAC_XSA_HDB_USER_ABC6' ], 
  [ 'SAC_XSA_HDB_USER_ABC7' ], [ 'SAC_XSA_HDB_USER_ABC8' ], 
  [ 'SAC_XSA_HDB_USER_ABC9' ], [ 'SAC_XSA_HDB_USER_ABC10' ] ]
  

Когда я запускаю свое приложение node,

Он не создает пользователей, и отображаемая ошибка не определена, как показано ниже —

 ERROR - Targeting User Creation

undefined
  

Я не уверен, почему это не удается? Он работает нормально, когда я использую exec() вместо execBatch() и указываю имя пользователя одно за другим в запросе create user (базовый механизм цикла).

Ответ №1:

Чтобы выяснить проблему, вы можете использовать HANA Studio или XSA SQL console, чтобы увидеть, что оператор CREATE USER ? PASSWORD "qwe" не может использовать заполнитель. Имя пользователя здесь является объектом, а заполнители являются только параметрами, они не могут заменять имя объекта.

Я не нашел ссылку на документ (это SAP, поэтому не удивлен), но это работает таким образом в других базах данных.

РЕДАКТИРОВАТЬ: под «объектом» я подразумеваю то, что сохраняется в системных таблицах базы данных: таблица, представление, последовательность, функция, пользователь, роль, привилегия и т.д. Это объект, который является частью вашей модели или частью системы, который вы можете «использовать» (вызывать, выбирать, создавать, изменять и т. Д.). Это часть синтаксиса (в документации, которую вы найдете для этого). Данные — это содержимое, которым вы можете манипулировать, и его можно заменить заполнителями. Конечно, метаданные тоже где-то хранятся, но это другой уровень абстракции.

Чтобы сделать ваше имя пользователя данными, вы должны написать некоторую процедуру, которая принимает имя пользователя, создает оператор SQL и выдает его EXECUTE IMMEDIATE (поэтому он вызывает анализатор SQL для анализа всей строки как есть). Затем вы должны вызвать эту процедуру с помощью ? в качестве параметра имени пользователя и передайте создаваемое динамическое имя пользователя.

 create procedure p_create_user( in p_uname nvarchar(20))
language sqlscript
sql security invoker
as
begin
  declare lv_sql nvarchar(1000);
  lv_sql := replace('create user <uname> password "QWEasd!23"', '<uname>', p_uname);
  execute immediate lv_sql;
end;

call p_create_user('demo');
  

Комментарии:

1. Можете ли вы немного объяснить, как узнать, когда это объект, а когда параметр?

2. @ShreyasiChakraborty Я обновил свой ответ и предоставил способ выполнения таких операторов динамическим способом.

3. Возможно ли реализовать то же самое в node.js без какой-либо помощи процедур или sql-скрипта?

4. @ShreyasiChakraborty Конечно, просто выполните инструкцию SQL «создать пользователя» для каждого элемента массива. Не знаю узла. JS и весь асинхронный персонал, поэтому процедурно это будет что-то вроде: for(String u : users) { do_db_call(«создать пользователя» u » пароль «MyPass » «) }

5. «создать пользователя » u » пароль «MyPass » » — не будет ли это подвержено sql-инъекции?