Marcadores de parâmetro

Aplica-se a:seleção marcada como sim Databricks SQL seleção marcada como sim Databricks Runtime

Os marcadores de parâmetro são variáveis tipadas de espaço reservado nomeadas ou sem nome usadas para fornecer valores da API invocando a instrução SQL.

O uso de marcadores de parâmetro protege seu código contra ataques de injeção de SQL, pois ele separa claramente os valores fornecidos da estrutura das instruções SQL.

Não é possível misturar marcadores de parâmetro nomeados e sem nome na mesma instrução SQL.

Você também pode usar marcadores de parâmetro na IDENTIFIER cláusula, que podem ser usados para parametrizar nomes de objeto. Consulte a cláusula IDENTIFIER.

Os marcadores de parâmetro podem ser fornecidos por:

As seguintes regras se aplicam:

  • Aplica-se a:marcado como sim Databricks SQL marcado como sim Databricks Runtime 17.3 LTS e anteriores

    • Você pode referenciar um marcador de parâmetro em uma expressão
    • Você não deve referenciar um marcador de parâmetro em uma instrução DDL, como uma coluna ou DEFAULT definição gerada, uma exibição ou uma função SQL. Exceções são referências a marcadores de parâmetro na cláusula IDENTIFIER, que podem ser usadas para parametrizar o tema de determinadas instruções DDL. Consulte a cláusula IDENTIFIER.
  • Aplica-se a:marcado como sim Databricks Runtime 18.0 e versões superiores

    • Você pode referenciar um marcador de parâmetro sempre que puder usar um literal do tipo do marcador de parâmetro. Isso eleva a restrição DDL anterior, permitindo marcadores de parâmetro em colunas, definições, DEFAULT exibições, funções SQL e cláusulas DDL com valor de cadeia de caracteres, como LOCATION.

Marcadores de parâmetro nomeados

Aplica-se a: Verificação do Databricks Runtime marcada como sim 12.1 e superior

Marcadores de parâmetro nomeados são variáveis de substituição tipadas. A API que invoca a instrução SQL deve fornecer pares nome-valor para associar cada marcador de parâmetro a um valor.

Sintaxe

 :parameter_name

Parâmetros

  • named_parameter_name

    Uma referência a um marcador de parâmetro fornecido na forma de um identificador não qualificado.

Anotações

Você pode referenciar o mesmo marcador de parâmetro várias vezes dentro da mesma Instrução SQL. Se nenhum valor tiver sido associado ao marcador de parâmetro, um erro UNBOUND_SQL_PARAMETER será gerado. Não é necessário fazer referência a todos os marcadores de parâmetro fornecidos.

O precedência : obrigatória (dois-pontos) diferencia o namespace de marcadores de parâmetro nomeados dos nomes de coluna e parâmetros SQL.

Exemplos

O exemplo a seguir define dois marcadores de parâmetro:

  • ** depois: Um INTERVAL HOUR com o valor 3.
  • x: A DOUBLE com o valor 15.0

x é referenciado várias vezes, enquanto later é referenciado uma 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 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|
// +----------------------------------------+------+

Aplica-se a: Verificação do Databricks Runtime marcada como sim 18.0 e superior

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

Marcadores de parâmetro sem nome

Aplica-se a: Databricks Runtime marcado com 'sim' 13.3 ou superior

Marcadores de parâmetro sem nome são variáveis de marcador de posição tipadas. A API que invoca a instrução SQL deve fornecer uma matriz de argumentos para associar cada marcador de parâmetro a um valor na ordem em que eles aparecem.

Sintaxe

 ?

Parâmetros

  • ?: uma referência a um marcador de parâmetro fornecido na forma de um ponto de interrogação.

Anotações

Cada ocorrência de um marcador de parâmetro sem nome consome um valor fornecido pela API invocando a instrução SQL em ordem. Se nenhum valor tiver sido associado ao marcador de parâmetro, um erro UNBOUND_SQL_PARAMETER será gerado. Você não precisa consumir todos os valores fornecidos.

Exemplos

O exemplo a seguir define três marcadores de parâmetro:

  • Um INTERVAL HOUR com o valor 3.
  • Dois DOUBLE com o valor 15.0 cada.

Como os parâmetros não são nomeados, cada valor fornecido é consumido pelo máximo um 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|
// +------+

Aplica-se a: Verificação do Databricks Runtime marcada como sim 18.0 e superior

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

Marcadores de parâmetro em cláusulas de cadeia de caracteres DDL

Algumas cláusulas DDL, como a LOCATION cláusula em CREATE TABLE, aceitam literais de cadeia de caracteres em vez de identificadores. Você não pode usar a IDENTIFIER cláusula para essas cláusulas porque elas não são nomes de objeto.

Aplica-se a: Verificação do Databricks Runtime marcada como sim 18.0 e superior

No Databricks Runtime 18.0 e superior, você pode usar marcadores de parâmetro diretamente nessas cláusulas porque o Databricks Runtime dá suporte a marcadores de parâmetro onde quer que aceite um literal do mesmo tipo. Por exemplo:

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

Para versões do Databricks Runtime antes da 18.0

Aplica-se a:check marked yes Databricks SQL check marked yes Databricks Runtime 14.3 to 17.3 LTS

Em versões anteriores ao Databricks Runtime 18.0, o Databricks Runtime não permite marcadores de parâmetro diretamente em instruções DDL (exceto por meio da IDENTIFIER cláusula). Você pode usar EXECUTE IMMEDIATE para criar a instrução SQL dinamicamente, concatenando o valor do caminho como um literal de cadeia de caracteres:

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

Note

Não é possível inserir um marcador de parâmetro dentro de um literal de cadeia de caracteres (por exemplo, 'abfss://:param/path'). Em vez disso, passe a cadeia de caracteres inteira como um único parâmetro ou use a concatenação de cadeia de caracteres para criar o valor antes de passá-lo. Por exemplo, use SET VARIABLE com CONCAT() para criar o caminho completo em uma variável e, em seguida, passe a variável para EXECUTE IMMEDIATE.