Маркеры параметров

Маркеры параметров называютсяили неименованные переменные заполнителя типа, используемые для предоставления значений из API, вызывающего инструкцию SQL.

Использование маркеров параметров защищает код от атак внедрения SQL, так как он четко отделяет предоставленные значения от инструкций SQL.

Маркеры именованных и неименованных параметров нельзя смешивать в той же инструкции SQL.

Не следует ссылаться на маркер параметра в инструкции DDL, например созданного столбца или DEFAULT определения, представления или функции SQL.

Исключения — это ссылки на маркеры параметров в IDENTIFIER предложении, которые можно использовать для параметризации имен таблиц или столбцов в определенных инструкциях DDL. См . предложение IDENTIFIER.

Маркеры параметров могут быть предоставлены следующими способами:

Именованные маркеры параметров

Область применения: Databricks Runtime check marked yes 12.1 и более поздних версий

Именованные маркеры параметров являются типизированными переменными заполнителя. API, вызывающий инструкцию SQL, должен предоставлять пары "имя-значение", чтобы связать каждый маркер параметра со значением.

Синтаксис

 :parameter_name

Параметры

  • named_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 check marked yes 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|
// +------+