# Onde são permitidos parâmetros dinâmicos

Os parâmetros dinâmicos podem ser utilizados em qualquer lugar da expressão onde seu tipo de dado pode ser facilmente deduzido.

1. É permitido o uso como primeiro operando do BETWEEN, se o segundo ou o terceiro operando não for um parâmetro dinâmico. O tipo de dado do primeiro operando é assumido como sendo o tipo de dado do parâmetro que não é dinâmico, ou o resultado da união dos tipos do segundo e do terceiro operandos, se estes dois não forem parâmetros dinâmicos.

       WHERE ? BETWEEN DATE('1996-01-01') AND ?
       -- tipos assumidos como sendo DATE

2. É permitido o uso como segundo ou terceiro operando do BETWEEN. O tipo de dado é assumido como sendo o tipo de dado do operando à esquerda.

       WHERE DATE('1996-01-01') BETWEEN ? AND ?
       -- tipos assumidos como sendo DATE

3. É permitido o uso como operando à esquerda da lista IN se pelo menos um item da lista não for um parâmetro dinâmico. O tipo de dado do operando à esquerda é assumido como sendo o resultado da união dos tipos de dado dos parâmetros não dinâmicos da lista.

       WHERE ? NOT IN (?, ?, 'Santiago')
       -- tipos assumidos como sendo CHAR

4. É permitido o uso na lista de valores do predicado IN, se o primeiro operando não for um parâmetro dinâmico, ou seu tipo foi determinado pela regra anterior. O tipo dos parâmetros dinâmicos que aparecem na lista de valores é assumido como sendo o tipo do operando à esquerda.

       WHERE ColunaPontoFlutuante IN (?, ?, ?)
       -- tipos assumidos como sendo FLOAT

5. Para os operadores binários +, -, *, /, AND, OR, <, >, =, <>, <= e >=, é permitido o uso do parâmetro dinâmico como um dos operandos, mas não os dois. Seu tipo de dado é obtido a partir do tipo do outro lado.

       WHERE ? < CURRENT_TIMESTAMP
       -- tipo assumido como sendo TIMESTAMP

6. A utilização em CAST é sempre permitida, porque CAST fornece tipo de dado ao parâmetro dinâmico.

       CALL valueOf(CAST (? AS VARCHAR(10)))

7. É permitido o uso nos dois lados do operador LIKE. Quando utilizado no lado esquerdo, o tipo de dado do parâmetro dinâmico é definido como sendo o tipo de dado do operando à direita, mas com o comprimento máximo permitido para o tipo de dado. Quando utilizado no lado direito, o tipo de dado é assumido como sendo do mesmo comprimento e tipo de dado do operando à esquerda (LIKE é permitido nos tipos de dado CHAR e VARCHAR; para obter mais informações deve ser consultado Concatenação).

       WHERE ? LIKE 'Santi%'
       -- tipo assumido como sendo CHAR com comprimento igual a
       -- java.lang.Integer.MAX_VALUE

8. O parâmetro ?, sem mais nada, é permitido em apenas um dos lados do operador ||, ou seja, "? || ?" não é permitido. O tipo do parâmetro ? de um dos lados do operador || é determinado pelo tipo da expressão do outro lado do operador ||. Se a expressão do outro lado for do tipo de dado CHAR ou VARCHAR, o tipo do parâmetro será VARCHAR com o comprimento máximo permitido para o tipo de dado. Se a expressão do outro lado for do tipo de dado CHAR FOR BIT DATA ou VARCHAR FOR BIT DATA, o tipo de dado do parâmetro será VARCHAR FOR BIT DATA com o comprimento máximo permitido para o tipo de dado.

       SELECT coluna_bit || ?
       FROM tabela_usuario
       -- tipo assumido como sendo CHAR FOR BIT DATA
       -- com o comprimento especificado para coluna_bit

9. Em uma expressão condicional, que utiliza ?, também é permitida a utilização do parâmetro dinâmico (que também é representado por ?). O tipo do parâmetro dinâmico como primeiro operando é assumido como sendo booleano. Com relação ao segundo e terceiro operandos, somente um dos dois pode ser um parâmetro dinâmico, e seu tipo é assumido como sendo o mesmo do outro operando (ou seja, o terceiro e segundo operando, respectivamente).

       SELECT c1 IS NULL ? ? : c1
       -- permite especificar o valor "padrão" em tempo de execução
       -- o parâmetro dinâmico é assumido como tendo o tipo de c1
       -- não podem haver parâmetros dinâmicos dos dois lados dos :

10. É permitido usar parâmetro dinâmico como item da lista de valores ou da lista de seleção da instrução INSERT. O tipo do parâmetro dinâmico é assumido como sendo o tipo da coluna de destino. O parâmetro ?, sem mais nada, não é permitido na lista de seleção, inclusive na lista de seleção da subconsulta, a menos que exista uma coluna correspondente em UNION, INTERSECT ou EXCEPT (consulte o nº 16, abaixo) que não seja dinâmica.

        INSERT INTO t VALUES (?)
        -- o parâmetro dinâmico é assumido como sendo
        -- do tipo da única coluna da tabela t
        INSERT INTO t SELECT ?
        FROM t2
        -- não é permitido

11. O parâmetro ? na comparação com uma subconsulta recebe seu tipo a partir da expressão sendo selecionada na subconsulta. Por exemplo:

        SELECT *
        FROM tab1
        WHERE ? = (SELECT x FROM tab2)

        SELECT *
        FROM tab1
        WHERE ? = ANY (SELECT x FROM tab2)
        -- Nos dois casos, o tipo do parâmetro dinâmico é
        -- assumido como sendo o mesmo tipo de tab2.x.

12. É permitido usar parâmetro dinâmico como o valor em uma instrução UPDATE. O tipo do parâmetro dinâmico é assumido como sendo o tipo da coluna na tabela de destino.

        UPDATE t2 SET c2 =? -- o tipo é assumido como sendo o tipo de c2

13. Não é permitido parâmetro dinâmico como operando dos operadores unários - e +.
14. LENGTH permite parâmetro dinâmico. O tipo é assumido como sendo o comprimento máximo do tipo VARCHAR.

        SELECT LENGTH(?)

15. Comparações qualificadas.

        ? = SOME (SELECT 1 FROM t)
        -- é válido. O parâmetro dinâmico é assumido como sendo do tipo INTEGER
        1 = SOME (SELECT ? FROM t)
        -- é válido. O parâmetro dinâmico é assumido como sendo do tipo INTEGER

16. É permitido usar parâmetro dinâmico para representar uma coluna se aparecer em uma expressão UNION, INTERSECT ou EXCEPT; O Derby pode inferir o tipo de dado a partir da coluna correspondente na expressão.

        SELECT ?
        FROM t
        UNION SELECT 1
        FROM t
        -- o parâmetro dinâmico é assumido como sendo INT
        VALUES 1 UNION VALUES ?
        -- o parâmetro dinâmico é assumido como sendo INT

17. É permitido parâmetro dinâmico como operando à esquerda de uma expressão IS, sendo assumido como booleano.

Uma vez que o tipo de dado do parâmetro dinâmico tenha sido determinado baseado na expressão onde se encontra, esta expressão pode estar em qualquer lugar onde normalmente seria permitida se não incluísse o parâmetro dinâmico. Por exemplo, acima foi dito que o parâmetro dinâmico não poderia ser utilizado como operando do - unário. Entretanto, pode aparecer em expressões que são operandos do menos unário, como:

    - (1+?)

O parâmetro dinâmico é assumido como sendo do tipo INTEGER (porque o outro operando operador binário + é do tipo INT). Como se sabe seu tipo, é permitido como operando do - unário.

Tópico pai: Parâmetros dinâmicos
Referências relacionadas
Exemplo de parâmetros dinâmicos