Udostępnij za pośrednictwem


Znaczniki parametrów

Znaczniki parametrów są nazwane lub nienazwane typu zmienne zastępcze używane do dostarczania values z interfejsu API wywołującego instrukcję SQL.

Użycie znaczników parametrów chroni kod przed atakami polegającymi na wstrzyknięciu kodu SQL, ponieważ wyraźnie oddziela values od instrukcji SQL.

Nie można mieszać znaczników nazwanych i nienazwanych parametrów w jednej instrukcji SQL.

Nie można odwoływać się do znacznika parametru w instrukcji DDL, takiej jak wygenerowana column lub definicja DEFAULT, widok lub funkcja SQL.

Wyjątki dotyczą odwołań do znaczników parametrów w klauzuli IDENTIFIER, które można wykorzystać do parametryzacji nazw table lub column w niektórych instrukcjach DDL. Zobacz klauzulę IDENTIFIER.

Znaczniki parametrów mogą być udostępniane przez:

  • Python przy użyciu interfejsu API pyspark.sql.SparkSession.sql().
  • Scala przy użyciu interfejsu API org.apache.spark.sql.SparkSession.sql().
  • Java przy użyciu API org.apache.spark.sql.SparkSession.sql().

Nazwane znaczniki parametrów

Dotyczy: Databricks Runtime zaznacz pole wyboru tak 12.1 i nowszych

Nazwane markery parametrów to typizowane zmienne zastępcze. Interfejs API wywołujący instrukcję SQL musi podać pary name-value, aby skojarzyć każdy znacznik parametru z wartością.

Składnia

 :parameter_name

Parameters

  • nazwa_parametru

    Odwołanie do podanego znacznika parametru w postaci niekwalifikowanego identifier.

Notatki

Możesz odwoływać się do tego samego znacznika parametru wiele razy w ramach tej samej instrukcji SQL. Jeśli żadna wartość nie została powiązana ze znacznikiem parametru, zostanie zgłoszony błąd UNBOUND_SQL_PARAMETER. Nie musisz odwoływać się do wszystkich podanych znaczników parametrów.

Obowiązkowy znak : (dwukropek) odróżnia przestrzeń nazw znaczników parametrów nazwanych od przestrzeni nazw column i SQL parameters.

Przykłady

W poniższym przykładzie zdefiniowano dwa znaczniki parametrów:

  • później: Element INTERVAL HOUR o wartości 3.
  • x: DOUBLE o wartości 15.0

x jest przywołyyny wiele razy, podczas gdy later jest przywołyny raz.

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|
// +----------------------------------------+------+

Jawa

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|
// +----------------------------------------+------+

Pyton

spark.sql("SELECT :x * :y * :z AS volume", args = { "x" : 3, "y" : 4, "z"  : 5 }).show()
// +------+
// |volume|
// +------+
// |    60|
// +------+

Znaczniki parametrów bez nazwy

Dotyczy: Databricks Runtime zaznacz pole wyboru tak 13.3 lub nowsze

Znaczniki parametrów bez nazwy to typowane zmienne zastępcze. Interfejs API wywołujący instrukcję SQL musi podać tablicę argumentów, aby skojarzyć każdy znacznik parametru z wartością w kolejności ich wyświetlania.

Składnia

 ?

Parameters

  • ?: odwołanie do podanego znacznika parametru w postaci znaku zapytania.

Notatki

Każde wystąpienie nienazwanego znacznika parametru zużywa wartość podaną przez interfejs API wywołując instrukcję SQL w kolejności. Jeśli żadna wartość nie została powiązana ze znacznikiem parametru, zostanie zgłoszony błąd UNBOUND_SQL_PARAMETER. Nie musisz spożywać wszystkich podanych values.

Przykłady

W poniższym przykładzie zdefiniowano trzy znaczniki parametrów:

  • Element INTERVAL HOUR o wartości 3.
  • Dwie DOUBLE, każda z wartością 15,0.

Ponieważ parameters są nienazwane, każda podana wartość jest zużywana przez co najwyżej jeden parametr.

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|
// +----------------------------------------+------+

Jawa

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|
// +----------------------------------------+------+

Pyton

spark.sql("SELECT ? * ? * ? AS volume", args = { 3, 4, 5 }).show()
// +------+
// |volume|
// +------+
// |    60|
// +------+