參數標記
參數標記是 命名 或 未命名的具型別 佔位元元變數,用來從叫用 SQL 語句的 API 提供值。
使用參數標記可保護您的程式代碼免於遭受 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 參數的命名空間。
範例
下列範例會定義兩個參數標記:
- 稍後:
INTERVAL HOUR
值為 3 的 。 - x:
DOUBLE
值為 15.0 的
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|
// +----------------------------------------+------+
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|
// +------+
未命名的參數標記
適用於: Databricks Runtime 13.3 和更新版本
未命名的參數標記是具類型的佔位元變數。 叫用 SQL 語句的 API 必須提供自變數陣列,以便讓每個參數標記與其出現的順序產生關聯。
語法
?
參數
?
:以問號形式提供之參數標記的參考。
備註
每次出現未命名的參數標記都會取用 API 依序叫用 SQL 語句所提供的值。 如果沒有值系結至參數標記, 則會引發UNBOUND_SQL_PARAMETER 錯誤。 您不需要取用所有提供的值。
範例
下列範例會定義三個參數標記:
INTERVAL HOUR
值為 3 的 。- 兩
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|
// +----------------------------------------+------+
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|
// +------+