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 APIpyspark.sql.SparkSession.sql(). Scala przy użyciu interfejsu API org.apache.spark.sql.SparkSession.sql(). Java przy użyciu APIorg.apache.spark.sql.SparkSession.sql().
Nazwane znaczniki parametrów
Dotyczy: Databricks Runtime 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
-
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 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|
// +------+