Маркеры параметров
Маркеры параметров называются или неименованные переменные заполнителя типа, используемые для предоставления значений из API, вызывающего инструкцию SQL.
Использование маркеров параметров защищает код от атак внедрения SQL, так как он четко отделяет предоставленные значения от инструкций SQL.
Маркеры именованных и неименованных параметров нельзя смешивать в той же инструкции SQL.
Не следует ссылаться на маркер параметра в инструкции DDL, например созданного столбца или DEFAULT
определения, представления или функции SQL.
Исключения — это ссылки на маркеры параметров в IDENTIFIER
предложении, которые можно использовать для параметризации имен таблиц или столбцов в определенных инструкциях DDL. См . предложение IDENTIFIER.
Маркеры параметров могут быть предоставлены следующими способами:
- Python с помощью API pyspark.sql.SparkSession.sql().
- Scala с помощью API org.apache.spark.sql.SparkSession.sql().
- Java с помощью API org.apache.spark.sql.SparkSession.sql().
Именованные маркеры параметров
Область применения: Databricks Runtime 12.1 и более поздних версий
Именованные маркеры параметров являются типизированными переменными заполнителя. API, вызывающий инструкцию SQL, должен предоставлять пары "имя-значение", чтобы связать каждый маркер параметра со значением.
Синтаксис
:parameter_name
Параметры
-
Ссылка на предоставленный маркер параметра в виде некавалифицированного идентификатора.
Примечания.
Один и тот же маркер параметров можно ссылаться несколько раз в одной инструкции SQL. Если значение не привязано к маркеру параметра, возникает ошибка UNBOUND_SQL_PARAMETER . Вам не требуется ссылаться на все предоставленные маркеры параметров.
Обязательный предыдущий :
(двоеточие) отличает пространство имен имен именованных маркеров параметров от имени именованных имен и параметров SQL.
Примеры
В следующем примере определяются два маркера параметров:
- позже: значение
INTERVAL HOUR
3. - x: A
DOUBLE
со значением 15.0
x
ссылается несколько раз, а later
ссылка на нее выполняется один раз.
SQL
> DECLARE stmtStr = 'SELECT current_timestamp() + :later, :x * :x AS square';
> EXECUTE IMMEDIATE stmtStr USING INTERVAL '3' HOURS AS later, 15.0 AS x;
2024-01-19 16:17:16.692303 225.00
Scala
import org.apache.spark.sql.SparkSession
val spark = SparkSession
.builder()
.appName("Spark named parameter marker example")
.getOrCreate()
val argMap = Map("later" -> java.time.Duration.ofHours(3), "x" -> 15.0)
spark.sql(
sqlText = "SELECT current_timestamp() + :later, :x * :x AS square",
args = argMap).show()
// +----------------------------------------+------+
// |current_timestamp() + INTERVAL '03' HOUR|square|
// +----------------------------------------+------+
// | 2023-02-27 17:48:...|225.00|
// +----------------------------------------+------+
Java
import org.apache.spark.sql.*;
import static java.util.Map.entry;
SparkSession spark = SparkSession
.builder()
.appName("Java Spark named parameter marker example")
.getOrCreate();
Map<String, String> argMap = Map.ofEntries(
entry("later", java.time.Duration.ofHours(3)),
entry("x", 15.0)
);
spark.sql(
sqlText = "SELECT current_timestamp() + :later, :x * :x AS square",
args = argMap).show();
// +----------------------------------------+------+
// |current_timestamp() + INTERVAL '03' HOUR|square|
// +----------------------------------------+------+
// | 2023-02-27 17:48:...|225.00|
// +----------------------------------------+------+
Python
spark.sql("SELECT :x * :y * :z AS volume", args = { "x" : 3, "y" : 4, "z" : 5 }).show()
// +------+
// |volume|
// +------+
// | 60|
// +------+
Неименованные маркеры параметров
Область применения: Databricks Runtime 13.3 и более поздних версий
Маркеры неназванных параметров являются типизированными переменными заполнителя. API, вызывающий инструкцию SQL, должен предоставить массив аргументов, чтобы связать каждый маркер параметра со значением в порядке, в котором они отображаются.
Синтаксис
?
Параметры
?
: ссылка на указанный маркер параметра в виде вопроса.
Примечания.
Каждое вхождение маркера неназванного параметра использует значение, предоставленное API, вызывая инструкцию SQL в порядке. Если значение не привязано к маркеру параметра, возникает ошибка UNBOUND_SQL_PARAMETER . Вам не требуется использовать все предоставленные значения.
Примеры
В следующем примере определяются три маркера параметров:
- Значение
INTERVAL HOUR
3. - Два
DOUBLE
со значением 15,0 каждый.
Так как параметры не именуются, каждое предоставленное значение потребляется по крайней мере одним параметром.
SQL
> DECLARE stmtStr = 'SELECT current_timestamp() + ?, ? * ? AS square';
> EXECUTE IMMEDIATE stmtStr USING INTERVAL '3' HOURS, 15.0, 15.0;
2024-01-19 16:17:16.692303 225.00
Scala
import org.apache.spark.sql.SparkSession
val spark = SparkSession
.builder()
.appName("Spark unnamed parameter marker example")
.getOrCreate()
val argArr = Array(java.time.Duration.ofHours(3), 15.0, 15.0)
spark.sql(
sqlText = "SELECT current_timestamp() + ?, ? * ? AS square", args = argArr).show()
// +----------------------------------------+------+
// |current_timestamp() + INTERVAL '03' HOUR|square|
// +----------------------------------------+------+
// | 2023-02-27 17:48:...|225.00|
// +----------------------------------------+------+
Java
import org.apache.spark.sql.*;
SparkSession spark = SparkSession
.builder()
.appName("Java Spark unnamed parameter marker example")
.getOrCreate();
Object[] argArr = new Object[] { java.time.Duration.ofHours(3), 15.0, 15.0 }
spark.sql(
sqlText = "SELECT current_timestamp() + ?, ? * ? AS square",
args = argArr).show();
// +----------------------------------------+------+
// |current_timestamp() + INTERVAL '03' HOUR|square|
// +----------------------------------------+------+
// | 2023-02-27 17:48:...|225.00|
// +----------------------------------------+------+
Python
spark.sql("SELECT ? * ? * ? AS volume", args = { 3, 4, 5 }).show()
// +------+
// |volume|
// +------+
// | 60|
// +------+