共用方式為


參數標記

參數標記可以是 名為 的,或是 未命名的 型別佔位符變數,用來提供從 API 叫用 SQL 語句時所需的值。

使用參數標記可保護您的程式代碼免於遭受 SQL 插入式攻擊,因為它會清楚地分隔提供的 SQL 語句值。

您無法在相同的 SQL 語句中混合具名和未命名的參數標記。

您不得參考 DDL 語句中的參數標記,例如產生的數據行或 DEFAULT 定義、檢視或 SQL 函式。

例外狀況是對 IDENTIFIER 子句中參數標記的引用,可用來將特定 DDL 語句中的資料表或欄位名稱參數化。 請參閱 IDENTIFIER 子句

參數標記可以透過:

具名參數標記

適用於: Databricks Runtime 已勾選為是 12.1 以上

具名參數標記是具類型的佔位符變數。 叫用 SQL 語句的 API 必須提供名稱/值組,讓每個參數標記與值產生關聯。

語法

 :parameter_name

參數

筆記

您可以在相同的 SQL 語句內多次參考相同的參數標記。 如果沒有值系結至參數標記,就會引發 UNBOUND_SQL_PARAMETER 錯誤。 您不需要參考所有提供的參數標記。

上述必要 :(冒號)會區分具名參數標記的命名空間與數據行名稱和 SQL 參數的命名空間。

例子

下列範例會定義兩個參數標記:

  • 後來:一個值為 3 的 INTERVAL HOUR
  • x:值為 15.0 的 DOUBLE

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

爪哇島

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 勾選是 13.3 及以上

未命名的參數標記是已定義類型的佔位元變數。 叫用 SQL 語句的 API 必須提供自變數陣列,以便讓每個參數標記與其出現的順序產生關聯。

語法

 ?

參數

  • ?:以問號形式提供之參數標記的參考。

筆記

未命名的參數標記每次出現時,會依序取用由 API 叫用的 SQL 語句中提供的值。 如果沒有值系結至參數標記,則會引發 UNBOUND_SQL_PARAMETER 錯誤。 您不需要使用所有提供的值。

例子

下列範例會定義三個參數標記:

  • 值為 3 的 INTERVAL HOUR
  • 兩個 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|
// +----------------------------------------+------+

爪哇島

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