На основе документов Snowflake:
Динамическое создание оператора SQL
Как указано в SQL Инъекция (в этом топи c), будьте осторожны, чтобы защититься от атак при использовании Dynami c SQL.
Создать хранимую процедуру. Эта процедура позволяет вам передать имя таблицы и получить количество строк в этой таблице (эквивалентно select count (*) из table_name):
create or replace procedure get_row_count(table_name VARCHAR)
returns float
not null
language javascript
as
$$
var row_count = 0;
// Dynamically compose the SQL statement to execute.
// Note that we uppercased the input parameter name.
var sql_command = "select count(*) from " + TABLE_NAME;
// Run the statement.
var stmt = snowflake.createStatement(
{
sqlText: sql_command
}
);
var res = stmt.execute();
// Get back the row count. Specifically, ...
// ... first, get the first (and in this case only) row from the
// result set ...
res.next();
// ... then extract the returned value (which in this case is the
// number of rows in the table).
row_count = res.getColumnValue(1);
return row_count;
$$
;
Приведенный пример не выглядит safe: "select count(*) from " + TABLE_NAME;
- простая конкатенация строк
Таким образом, можно запускать такой код:
CALL get_row_count('TAB'); -- intended use
CALL get_row_count('(SELECT * FROM TAB UNION ALL SELECT * FROM TAB) s'); -- subquery
Первой идеей было запустить код с помощью функции TABLE/IDENTIFIER
(в лист будет выглядеть так):
SET TABLE_NAME = 'TAB'; -- works
SET TABLE_NAME = '(SELECT * FROM TAB UNION SELECT * FROM TAB) s';
-- error: error line 1 at position 27 invalid identifier '$TABLE_NAME'
SELECT COUNT(*) FROM TABLE($TABLE_NAME);
И как часть процедуры:
var sql_command = "SET TABLE_NAME = " + TABLE_NAME + "; SELECT COUNT(*) FROM TABLE($TABLE_NAME);";
Но это не будет работать, так как:
Ошибка выполнения в хранимой процедуре GET_ROW_COUNT: Несколько SQL операторов в одном вызове API не поддерживаются; используйте вместо одного вызова API один оператор .
Используя TABLE/IDENTIFIER
и переменную привязки:
create or replace procedure get_row_count(table_name VARCHAR)
returns float
not null
language javascript
as
$$
var row_count = 0;
// Dynamically compose the SQL statement to execute.
// Note that we uppercased the input parameter name.
var sql_command = "select count(*) from TABLE(:1)";
// Run the statement.
var stmt = snowflake.createStatement(
{
sqlText: sql_command,
binds: [TABLE_NAME]
}
);
var res = stmt.execute();
res.next();
row_count = res.getColumnValue(1);
return row_count;
$$
;
Вызов:
CALL get_row_count('TAB'); --works
CALL get_row_count('(SELECT * FROM TAB UNION ALL SELECT * FROM TAB) s');
-- SQL compilation error: syntax error line 1 at position 0 unexpected '('.
Вопросы:
- Можно ли как-то запустить несколько операторов в одном пакете (
snowflake.createStatement
)? Есть ли опция для безопасно квотенем в JS, вроде:
var sql_command = "select count(*) from " + FUNC(TABLE_NAME);
Есть ли потенциальные fl aws с TABLE
и значениями привязки подход?