Техническое решение @SonOfHarpy работает, но имеет несколько проблем, а именно:
- ненужное использование временных таблиц
- чрезмерно сложный подход к присвоению строк
- использованиеисправлена схема системной таблицы (
SYS.TABLE_COLUMNS
) вместо синонима PUBLIC - неверный тип данных и имя переменной для входного параметра
Улучшенная версия кода выглядит следующим образом:
create procedure SHA_PREP (in TABLE_NAME nvarchar(256))
as
begin
declare SQL_STR nvarchar(5000);
SELECT
'UPDATE "SCHEMA_NAME"."TABLE_NAME" SET "SHA"= hash_sha256(' || STRING_AGG(A, ', ') || ')'
into SQL_STR
FROM (
SELECT
'TO_VARBINARY(IFNULL("'|| "COLUMN_NAME" ||'",''0''))' as A
FROM TABLE_COLUMNS
WHERE
"SCHEMA_NAME" = 'SCHEMA_NAME'
AND "TABLE_NAME" = :TABLE_NAME
AND "COLUMN_NAME" != 'SHA'
ORDER BY POSITION
);
-- select :sql_str from dummy; -- this is for debugging output only
EXECUTE IMMEDIATE (:SQL_STR);
end;
Путем изменения функций CONCAT
на более короткий оператор ||
(double-pipe) код становится намного проще для чтения, поскольку ранее вложенные вызовы функций теперь являются простыми сцепленными цепочками.
С помощью SELECT ... INTO variable
можно избежать всей бессмыслицы с временной таблицей, что снова делает код более простым для понимания и менее подверженным проблемам.
Имя входного параметра теперь правильно отражает егоозначает и отражает тип данных словаря HANA для TABLE_NAME
(NVARCHAR(256)
).
Процедура теперь состоит из двух команд (SELECT
и EXECUTE IMMEDIATE
), каждая из которых выполняет существенную задачу процедуры:
- Создание допустимой строки команды обновления SQL.
- Выполнение команды SQL.
Я удалил бесполезные строковые комментарии, но оставил оператор отладки в качестве комментария в коде, чтобы можно было просмотреть строку SQL без необходимостивыполнить команду.Очевидно, что для того, чтобы это работало, строку EXECUTE...
необходимо закомментировать, а строку отладки - не закомментировать.
Его назначение вызывает большее беспокойство, чем создание решения.Выглядит так, как будто столбец SHA
должен использоваться как своего рода сокращенный отпечаток строки данных.Подход UPDATE
, безусловно, обрабатывает это как запоздалое действие, но оставляет «отпечатки пальцев» на время выполнения обновления.
Кроме того, он занимает существенную часть дизайна таблицы (чтостолбец SHA
должен содержать отпечаток пальца) вне определения таблицы.
Альтернативой этому может быть ОБЩАЯ КОЛОННА:
create table test (aaa int, bbb int);
alter table test add (sha varbinary (256) generated always as
hash_sha256(to_varbinary(IFNULL("AAA",'0'))
, to_varbinary(IFNULL("BBB",'0'))
)
);
insert into test (aaa, bbb) values (12, 32);
select * from test;
/*
AAA BBB SHA
12 32 B6602F58690CA41488E97CD28153671356747C951C55541B6C8D8B8493EB7143
*/
При этом подход "генератора" можетбудет использоваться для определения / изменения таблицы, но вся фактическая обработка данных будет автоматически выполняться HANA при каждом изменении значений в таблице.
Кроме того, не требуется никаких отдельных вызовов процедуры, так как отпечатки пальцев всегда будутбудь в курсе.