Marcadores de parámetros

Los marcadores de parámetro se denominan o las variables de marcador de posición con tipo sin nombre que se usan para proporcionar valores de la API que invocan la instrucción SQL.

El uso de marcadores de parámetros protege el código frente a ataques por inyección de código SQL, ya que separa claramente los valores proporcionados de las instrucciones SQL.

No se pueden mezclar marcadores de parámetros con nombre y sin nombre en la misma instrucción SQL.

No debe hacer referencia a un marcador de parámetro en una instrucción DDL, como una columna o definición DEFAULT generada, una vista o una función SQL.

Las excepciones son referencias a marcadores de parámetros en la cláusulaIDENTIFIER, que se pueden usar para parametrizar nombres de tabla o columna en determinadas instrucciones DDL. Consulte Cláusula IDENTIFICADOR.

Los marcadores de parámetros se pueden proporcionar mediante:

Marcadores de parámetros con nombre

Se aplica a: Databricks Runtime check marked yes 12.1 y versiones posteriores

Los marcadores de parámetro con nombre son variables de marcador de posición con tipo. La API que invoca la instrucción SQL debe proporcionar pares nombre-valor para asociar cada marcador de parámetro a un valor.

Sintaxis

 :parameter_name

Parámetros

  • named_parameter_name

    Referencia a un marcador de parámetro proporcionado en forma de identificador no calificado.

Notas

Puede hacer referencia al mismo marcador de parámetro varias veces dentro de la misma instrucción SQL. Si no se ha enlazado ningún valor al marcador de parámetro, se produce un errorUNBOUND_SQL_PARAMETER. No es necesario hacer referencia a todos los marcadores de parámetro proporcionados.

El precedente obligatorio : (dos puntos) diferencia el espacio de nombres de los marcadores de parámetro con nombre de los nombres de columna y los parámetros SQL.

Ejemplos

En el ejemplo siguiente se definen dos marcadores de parámetro:

  • más adelante: un INTERVAL HOUR con el valor 3.
  • x: un DOUBLE con el valor 15.0

x se hace referencia varias veces, mientras later se hace referencia a una vez.

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

Marcadores de parámetro sin nombre

Se aplica a: Databricks Runtime check marked yes 13.3 y versiones posteriores

Los marcadores de parámetro sin nombre son variables de marcador de posición con tipo. La API que invoca la instrucción SQL debe proporcionar una matriz de argumentos para asociar cada marcador de parámetro a un valor en el orden en que aparecen.

Sintaxis

 ?

Parámetros

  • ?: referencia a un marcador de parámetro proporcionado en forma de signo de interrogación.

Notas

Cada aparición de un marcador de parámetro sin nombre consume un valor proporcionado por la API que invoca la instrucción SQL en orden. Si no se ha enlazado ningún valor al marcador de parámetros, se genera un error UNBOUND_SQL_PARAMETER. No es necesario consumir todos los valores proporcionados.

Ejemplos

En el ejemplo siguiente se definen tres marcadores de parámetro:

  • Un INTERVAL HOUR con el valor 3.
  • Dos DOUBLE con el valor 15,0 cada uno.

Dado que los parámetros no tienen nombre, cada valor proporcionado se consume como máximo en un parámetro.

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