パラメーターマーカー

適用対象:チェック済み: はい Databricks SQLチェック済み: はい Databricks Runtime

パラメーター マーカーは、SQL ステートメントを呼び出す API から値を指定するために使用される 名前付き または 名前のない 型指定されたプレースホルダー変数です。

パラメーター マーカーを使用すると、指定された値が SQL ステートメントの構造から明確に分離されるため、SQL インジェクション攻撃からコードが保護されます。

名前付きパラメーター マーカーと名前なしパラメーター マーカーを同じ SQL ステートメントに混在させることはできません。

IDENTIFIER句でパラメーター マーカーを使用することもできます。このマーカーを使用して、オブジェクト名をパラメーター化することもできます。 IDENTIFIER の条項を参照してください。

パラメーター マーカーは、次の方法で指定できます。

次の規則が適用されます。

  • 適用対象:チェックマーク はい Databricks SQL チェックマーク はい Databricks Runtime 17.3 LTS およびそれ以前

    • でパラメーター マーカーを参照できます
    • 生成された列や DEFAULT 定義、ビュー、SQL 関数など、DDL ステートメントでパラメーター マーカーを参照することはできません。 例外は、特定の DDL ステートメントのサブジェクトをパラメーター化するために使用できる、 IDENTIFIER 句のパラメーター マーカーへの参照です。 IDENTIFIER の条項を参照してください。
  • 適用対象:Databricks Runtime 18.0 以上で「はい」とチェックマークがつけられている

    • パラメーターマーカーは、その型のリテラルを使用できる場所であればどこでも参照できます。 これにより、上記の DDL 制限が解除され、生成された列、 DEFAULT 定義、ビュー、SQL 関数、および文字列値 DDL 句 ( LOCATION など) のパラメーター マーカーが許可されます。

名前付きパラメーター マーカー

適用対象: Databricks Runtime チェックが 12.1 以上" とマークされている

名前付きパラメーター マーカーは、型指定されたプレースホルダー変数です。 SQL ステートメントを呼び出す API は、各パラメーター マーカーを値に関連付けるために、名前と値のペアを指定する必要があります。

構文

 :parameter_name

パラメーター

  • named_parameter_name

    修飾されていない識別子の形式で指定されたパラメーター マーカーへの参照。

注記

同じ SQL ステートメント内で同じパラメーター マーカーを複数回参照できます。 パラメーター マーカーに値がバインドされていない場合は、 UNBOUND_SQL_PARAMETER エラーが発生します。 指定されたすべてのパラメーター マーカーを参照する必要はありません。

必須の前の : (コロン) は、名前付きパラメーター マーカーの名前空間と列名と SQL パラメーターの名前空間を区別します。

例示

次の例では、2 つのパラメーター マーカーを定義します。

  • later: 値が3のINTERVAL HOUR
  • x: 値が 15.0 のDOUBLE

x は複数回参照されますが、 later は 1 回参照されます。

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

適用対象: Databricks Runtime チェックが 18.0 以上" とマークされている

> 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;

名前のないパラメーター マーカー

適用対象: Databricks Runtime チェックが 13.3 以上" とマークされている

名前のないパラメーター マーカーは、型指定されたプレースホルダー変数です。 SQL ステートメントを呼び出す API は、各パラメーター マーカーを表示順序の値に関連付けるために、引数の配列を指定する必要があります。

構文

 ?

パラメーター

  • ?: 指定されたパラメーター マーカーへの参照 (疑問符の形式)。

注記

名前のないパラメーター マーカーが出現するたびに、SQL ステートメントを呼び出す API によって提供される値が順番に使用されます。 パラメーター マーカーに値がバインドされていない場合は、 UNBOUND_SQL_PARAMETER エラーが発生します。 指定されたすべての値を使用する必要はありません。

例示

次の例では、3 つのパラメーター マーカーを定義します。

  • 値 3 の INTERVAL HOUR
  • 各値が15.0のDOUBLEが2つあります。

パラメーターは名前が付いていないため、指定された各値は最大 1 つのパラメーターで使用されます。

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

適用対象: Databricks Runtime チェックが 18.0 以上" とマークされている

> 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';

DDL 文字列句のパラメーター マーカー

一部の DDL 句 (CREATE TABLELOCATION 句など) は、識別子ではなく文字列リテラルを受け入れます。 これらの句はオブジェクト名ではないので、 IDENTIFIER 句を使用することはできません。

適用対象: Databricks Runtime チェックが 18.0 以上" とマークされている

Databricks Runtime 18.0 以降では、Databricks Runtime は同じ型のリテラルを受け入れる場所であればどこでもパラメーター マーカーをサポートするため、これらの句でパラメーター マーカーを直接使用できます。 例えば次が挙げられます。

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);

18.0 より前の Databricks Runtime バージョンの場合

適用対象:はい Databricks SQL チェックが チェック Databricks Runtime 14.3 から 17.3 LTS

Databricks Runtime 18.0 より前のバージョンでは、Databricks Runtime は DDL ステートメントでパラメーター マーカーを直接許可しません ( IDENTIFIER 句を除く)。 EXECUTE IMMEDIATEを使用して SQL ステートメントを動的にビルドし、パス値を文字列リテラルとして連結できます。

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

文字列リテラル内にパラメーター マーカーを埋め込むことはできません (たとえば、 'abfss://:param/path')。 代わりに、文字列全体を 1 つのパラメーターとして渡すか、文字列連結を使用して値を渡す前に値を作成します。 たとえば、CONCAT()SET VARIABLEを使用して変数の完全なパスを作成し、変数をEXECUTE IMMEDIATEに渡します。