Маркеры параметров
Маркеры параметров именованные или неименованные переменные заполнители типа, которые используются для передачи values из API, вызывающего SQL-инструкцию.
Использование маркеров параметров защищает код от атак внедрения SQL, так как он четко отделяет предоставленные values от инструкций SQL.
Маркеры именованных и неименованных параметров нельзя смешивать в той же инструкции SQL.
Не следует ссылаться на маркер параметра в инструкции DDL, например созданное column или определение DEFAULT
, представление или функцию SQL.
Исключения — это ссылки на маркеры параметров в предложении IDENTIFIER
, которые можно использовать для параметризации table или column имен в определенных инструкциях DDL. См. пункты IDENTIFIER.
Маркеры параметров могут быть предоставлены следующими способами:
Python с использованием APIpyspark.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
Parameters
-
Ссылка на указанный маркер параметра в виде некавалифицированного identifier.
Примечания
Один и тот же маркер параметров можно ссылаться несколько раз в одной инструкции SQL. Если значение не было привязано к маркеру параметра, возникает ошибка UNBOUND_SQL_PARAMETER. Вам не требуется ссылаться на все предоставленные маркеры параметров.
Обязательный префикс :
(двоеточие) отличает пространство имен именованных маркеров параметров от пространства имен column и SQL parameters.
Примеры
В следующем примере определяются два маркера параметров:
-
позже:
INTERVAL HOUR
со значением 3. -
x:
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|
// +----------------------------------------+------+
Ява
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|
// +----------------------------------------+------+
Питон
spark.sql("SELECT :x * :y * :z AS volume", args = { "x" : 3, "y" : 4, "z" : 5 }).show()
// +------+
// |volume|
// +------+
// | 60|
// +------+
Неименованные маркеры параметров
применимо: Databricks Runtime 13.3 и более поздних версий
Обозначения безымянных параметров являются типизированными переменными-шаблонами. API, вызывающий инструкцию SQL, должен предоставить массив аргументов, чтобы связать каждый маркер параметра со значением в порядке, в котором они отображаются.
Синтаксис
?
Parameters
-
?
: Ссылка на предоставленный маркер параметра в виде вопросительного знака.
Примечания
Каждое вхождение маркера неназванного параметра использует значение, предоставленное API, при выполнении SQL инструкции последовательно. Если значение не привязано к маркеру параметра, возникает ошибка UNBOUND_SQL_PARAMETER. Вам не требуется потреблять все предоставленные values.
Примеры
В следующем примере определяются три маркера параметров:
-
INTERVAL HOUR
со значением 3. - Два
DOUBLE
со значением 15,0 каждый.
Так как parameters не именуются, каждое предоставленное значение потребляется по крайней мере одним параметром.
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|
// +----------------------------------------+------+
Ява
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|
// +----------------------------------------+------+
Питон
spark.sql("SELECT ? * ? * ? AS volume", args = { 3, 4, 5 }).show()
// +------+
// |volume|
// +------+
// | 60|
// +------+