參數標記
參數標記可以是 名為 的,或是 未命名的 型別佔位符變數,用來提供從 API 叫用 SQL 語句時所需的值。
使用參數標記可保護您的程式代碼免於遭受 SQL 插入式攻擊,因為它會清楚地分隔提供的 SQL 語句值。
您無法在相同的 SQL 語句中混合具名和未命名的參數標記。
您不得參考 DDL 語句中的參數標記,例如產生的數據行或 DEFAULT
定義、檢視或 SQL 函式。
例外狀況是對 IDENTIFIER
子句中參數標記的引用,可用來將特定 DDL 語句中的資料表或欄位名稱參數化。 請參閱 IDENTIFIER 子句。
參數標記可以透過:
- Python 使用其 pyspark.sql.SparkSession.sql() API。
- Scala 使用其 org.apache.spark.sql.SparkSession.sql() API。
- Java 使用其 org.apache.spark.sql.SparkSession.sql() API。
具名參數標記
適用於: 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|
// +------+