Parametermarker
Parametermarkierungen sind benannte oder nicht benannte typbehaftete Platzhaltervariablen zum Bereitstellen von Werten aus der API, die die SQL-Anweisung aufruft.
Die Verwendung von Parametermarkierungen schützt Ihren Code vor Angriffen durch Einschleusung von SQL-Befehlen, da er die bereitgestellten Werte eindeutig von den SQL-Anweisungen trennt.
Sie können benannte und nicht benannte Parametermarkierungen nicht in derselben SQL-Anweisung kombinieren.
Sie dürfen nicht in DDL-Anweisungen auf Parametermarkierungen verweisen, z. B. in generierten Spalten oder DEFAULT
-Definitionen, Ansichten oder SQL-Funktionen.
Ausnahmen bilden Verweise auf Parametermarkierungen in der IDENTIFIER
-Klausel, die in bestimmten DDL-Anweisungen zum Parametrisieren von Tabellen- oder Spaltennamen verwendet werden können. Weitere Informationen finden Sie unter IDENTIFIER-Klausel.
Parametermarkierungen können folgendermaßen bereitgestellt werden:
- In Python mit der pyspark.sql.SparkSession.sql()-API.
- In Scala mit der org.apache.spark.sql.SparkSession.sql()-API.
- In Java mit der org.apache.spark.sql.SparkSession.sql()-API.
Benannte Parametermarkierungen
Gilt für: Databricks Runtime 12.1 und höher
Benannte Parametermarkierungen sind typbehaftete Platzhaltervariablen. Die API, die die SQL-Anweisung aufruft, muss mithilfe von Name-Wert-Paaren jeder Parametermarkierung einem Wert zuordnen.
Syntax
:parameter_name
Parameter
-
Ein Verweis auf eine angegebene Parametermarkierung in Form eines nicht qualifizierten Bezeichners.
Hinweise
Sie können mehrmals innerhalb derselben SQL-Anweisung auf dieselbe Parametermarkierung verweisen. Wenn kein Wert an die Parametermarkierung gebunden wurde, wird der Fehler UNBOUND_SQL_PARAMETER ausgelöst. Sie müssen nicht auf alle angegebenen Parametermarkierungen verweisen.
Die obligatorische vorangehende :
(Doppelpunkt) unterscheidet den Namespace der benannten Parametermarkierungen von denen von Spaltennamen und SQL-Parametern.
Beispiele
Im folgenden Beispiel werden zwei Parametermarkierungen definiert:
- later: ein
INTERVAL HOUR
mit dem Wert 3. - x: ein
DOUBLE
mit dem Wert 15,0
x
wird mehrmals referenziert, während later
einmal referenziert wird.
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|
// +------+
Nicht bekannte Parametermarkierungen
Gilt für: Databricks Runtime 13.3 und höher
Nicht benannte Parametermarkierungen sind typbehaftete Platzhaltervariablen. Die API, die die SQL-Anweisung aufruft, muss mithilfe eines Arrays von Argumenten jede Parametermarkierung einem Wert in der Reihenfolge des Auftretens zuzuordnen.
Syntax
?
Parameter
?
: ein Verweis auf eine angegebene Parametermarkierung in Form eines Fragezeichens.
Hinweise
Jedes Auftreten einer nicht benannten Parametermarkierung verwendet einen von der API bereitgestellten Wert, der die SQL-Anweisung in der entsprechenden Reihenfolge aufruft. Wenn kein Wert an die Parametermarkierung gebunden wurde, wird der Fehler UNBOUND_SQL_PARAMETER ausgelöst. Sie müssen nicht alle bereitgestellten Werte verwenden.
Beispiele
Im folgenden Beispiel werden drei Parametermarkierungen definiert:
- Ein
INTERVAL HOUR
mit dem Wert 3. - Zwei
DOUBLE
jeweils mit dem Wert 15,0.
Da die Parameter nicht benannt sind, wird jeder bereitgestellte Wert von höchstens einem Parameter verwendet.
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|
// +------+