Parametermarkörer

gäller för:markerad med ja Databricks SQL markerad med ja Databricks Runtime

Parametermarkörer är namngivna eller namnlösa typade platshållarvariabler som används för att tillhandahålla värden från API:et som anropar SQL-instruktionen.

Med hjälp av parametermarkörer skyddar du koden från SQL-inmatningsattacker eftersom den tydligt separerar angivna värden från strukturen för SQL-uttrycken.

Du kan inte blanda namngivna och namnlösa parametermarkörer i samma SQL-instruktion.

Du kan också använda parametermarkörer i IDENTIFIER -satsen, som kan användas för att parametrisera objektnamn. Se IDENTIFIER-satsen.

Parametermarkörer kan anges av:

Följande regler gäller:

  • Gäller för:checkmarkerad ja Databricks SQL checkmarkerad ja Databricks Runtime 17.3 LTS och tidigare

    • Du kan referera till en parametermarkör i ett uttryck
    • Du får inte referera till en parametermarkör i en DDL-instruktion, till exempel en genererad kolumn eller DEFAULT definition, en vy eller en SQL-funktion. Undantag är referenser till parametermarkörer i IDENTIFIER -satsen, som kan användas för att parametrisera ämnet för vissa DDL-instruktioner. Se IDENTIFIER-satsen.
  • Gäller för:markerad som ja Databricks Runtime 18.0 och senare

    • Du kan referera till en parametermarkör där du kan använda en literal av parametermarkörens typ. Detta lyfter den föregående DDL-begränsningen och tillåter parametermarkörer i genererade kolumner, DEFAULT definitioner, vyer, SQL-funktioner och strängvärdes-DDL-satser som LOCATION.

Namngivna parametermarkörer

gäller för: Databricks Runtime kontrollera markerat ja 12.1 och senare

Namngivna parametermarkörer är typindelade platshållarvariabler. API:et som anropar SQL-instruktionen måste ange namn/värde-par för att associera varje parametermarkör med ett värde.

Syntax

 :parameter_name

Parametrar

Anteckningar

Du kan referera till samma parametermarkör flera gånger inom samma SQL-instruktion. Om inget värde har bundits till parametermarkören utlöses ett UNBOUND_SQL_PARAMETER fel. Du behöver inte referera till alla angivna parametermarkörer.

Det obligatoriska föregående : (kolon) skiljer namnområdet för namngivna parametermarkörer från kolumnnamn och SQL-parametrar.

Exempel

I följande exempel definieras två parametermarkörer:

  • senare: En INTERVAL HOUR med värdet 3.
  • x: En DOUBLE med värdet 15,0

x refereras flera gånger, medan later refereras en gång.

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 current_timestamp() + :later, :x * :x AS square",
  args = { "later": datetime.timedelta(hours=3), "x": 15.0 }).show()
// +----------------------------------------+------+
// |current_timestamp() + INTERVAL '03' HOUR|square|
// +----------------------------------------+------+
// |                    2023-02-27 17:48:...|225.00|
// +----------------------------------------+------+

Gäller för: Databricks Runtime kontrollmarkerad som ja 18.0 och senare

> EXECUTE IMMEDIATE 'SELECT 1::DECIMAL(:precision, :scale)' USING 6 AS precision, 4 AS scale;
  1.0000

> EXECUTE IMMEDIATE 'CREATE VIEW v(c1 INT) AS SELECT :val AS c1' USING 10 AS val;
> SELECT * FROM v;
  10

> EXECUTE IMMEDIATE 'CREATE TABLE T(c1 INT DEFAULT :def COMMENT \'This is a \' :com)' USING 17 AS def, 'comment' AS com;

Namnlösa parametermarkörer

Gäller för: Databricks Runtime markera ja 13.3 och senare

Namnlösa parametermarkörer är typindelade platshållarvariabler. API:et som anropar SQL-instruktionen måste ange en matris med argument för att associera varje parametermarkör med ett värde i den ordning de visas.

Syntax

 ?

Parametrar

  • ?: En referens till en angiven parametermarkör i form av ett frågetecken.

Anteckningar

Varje förekomst av en namnlös parametermarkör förbrukar ett värde som tillhandahålls av API:et som anropar SQL-instruktionen i ordning. Om inget värde har bundits till parametermarkören utlöses ett UNBOUND_SQL_PARAMETER fel. Du behöver inte använda alla angivna värden.

Exempel

I följande exempel definieras tre parametermarkörer:

  • En INTERVAL HOUR med värdet 3.
  • Två DOUBLE med värdet 15,0 vardera.

Eftersom parametrarna inte är namngivna förbrukas varje angivet värde av högst en parameter.

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

Gäller för: Databricks Runtime kontrollmarkerad som ja 18.0 och senare

> EXECUTE IMMEDIATE 'SELECT 1::DECIMAL(?, ?)' USING 6, 4;
  1.0000

> EXECUTE IMMEDIATE 'CREATE VIEW v(c1 INT) AS SELECT ? AS c1' USING 10;
> SELECT * FROM v;
  10

> EXECUTE IMMEDIATE 'CREATE TABLE T(c1 INT DEFAULT ? COMMENT \'This is a \' ?)' USING 17, 'comment';

Parametermarkörer i DDL-strängsatser

Vissa DDL-satser, till exempel LOCATION -satsen i CREATE TABLE, accepterar strängliteraler i stället för identifierare. Du kan inte använda IDENTIFIER -satsen för dessa satser eftersom de inte är objektnamn.

Gäller för: Databricks Runtime kontrollmarkerad som ja 18.0 och senare

I Databricks Runtime 18.0 och senare kan du använda parametermarkörer direkt i dessa satser eftersom Databricks Runtime stöder parametermarkörer där den accepterar en literal av samma typ. Ett exempel:

SQL

> CREATE EXTERNAL TABLE my_table USING DELTA LOCATION :path;

Python

spark.sql(
  "CREATE EXTERNAL TABLE my_table USING DELTA LOCATION :path",
  args = {"path": "abfss://container@account.dfs.core.windows.net/data"})

Scala

val argMap = Map("path" -> "abfss://container@account.dfs.core.windows.net/data")
spark.sql(
  sqlText = "CREATE EXTERNAL TABLE my_table USING DELTA LOCATION :path",
  args = argMap)

Java

Map<String, String> argMap = Map.ofEntries(
  entry("path", "abfss://container@account.dfs.core.windows.net/data")
);

spark.sql(
  sqlText = "CREATE EXTERNAL TABLE my_table USING DELTA LOCATION :path",
  args = argMap);

För Databricks Runtime-versioner före 18.0

Gäller för:check markerad ja Databricks SQL-kontroll markerad ja Databricks Runtime 14.3 till 17.3 LTS

I versioner före Databricks Runtime 18.0 tillåter Databricks Runtime inte parametermarkörer direkt i DDL-instruktioner (förutom via IDENTIFIER -satsen). Du kan använda EXECUTE IMMEDIATE för att skapa SQL-instruktionen dynamiskt och sammanfoga sökvägsvärdet som en strängliteral:

> DECLARE path STRING DEFAULT 'abfss://container@account.dfs.core.windows.net/data';
> EXECUTE IMMEDIATE 'CREATE EXTERNAL TABLE my_table USING DELTA LOCATION \'' || path || '\'';

Note

Du kan inte bädda in en parametermarkör i en strängliteral (till exempel 'abfss://:param/path'). Skicka i stället hela strängen som en enskild parameter eller använd strängsammanfogning för att skapa värdet innan du skickar det. Använd till exempel SET VARIABLE med CONCAT() för att skapa den fullständiga sökvägen i en variabel och skicka sedan variabeln till EXECUTE IMMEDIATE.