Embedded Sql - Expressão ou estrutura para substituição ao utilizar o operador de continência IN

Olá, pessoal!

Não encontrei qualquer referência a alguma expressão ou estrutura para utilização com o operador de continência IN, no Sql, para a substituição de conjuntos que são variáveis.

Imaginem uma lista de códigos selecionados pelo usuário e essa lista deve ser utilizada na cláusula WHERE para filtragem dos dados. Exemplo:

BeginSQL Alias 'SB1TMP' SELECT SB1.B1_COD, SB1.B1_DESC, SB1.B1_GRUPO, SB1.B1_TIPO FROM SB1010 AS SB1 WHERE SB1.D_E_L_E_T_ = ' ' AND SB1.B1_FILIAL = %xFilial:SB1% AND SB1.B1_TIPO IN (TiposSelecionadosPeloUsuario) EndSQL

Por ser uma lista variável, como seria possível a substituição no script Sql acima, em (TiposSelecionadosPeloUsuario)?

Cordialmente,

Jesus Ramos.

Boa tarde, Jesus!

Nessa situação eu costumo utilizar a função FormatIn em conjunto com o simbolo de porcentagem (%), segue exemplo:


cCodFab := ArrTokStr(aCodFab)    // resultado '01|02|03'

cCodFab := StrTran(cCodFab, '|', ',') // resultado '01,02,03'

cCodFab := '%' + FormatIn(cCodFab, ',') + '%' // resultado '('01','02','03)'

_cAlias    := GetNextAlias()

BeginSql Alias _cAlias

    SELECT COUNT(*) CNT FROM
    (
        SELECT DISTINCT
            ZMF.ZMF_CODIGO 
        FROM %TABLE:ZMF% (NOLOCK) ZMF
        WHERE 
            ZMF.ZMF_FILIAL = %xFilial:ZMF% AND
            ZMF.ZMF_CODFAB IN %Exp:cCodFab% AND 
            ZMF.%NOTDEL%
    ) A

EndSql

Giordano, por favor, poderia explicar o porquê do caracter “%” (porcentagem) na expressão: cCodFab := ‘%’ + FormatIn(cCodFab, ‘,’) + ‘%’ // resultado '(‘01’,‘02’,‘03)’ ?

Maicon, internamente o BeginSql irá fazer a substituição do conteúdo entre os caracteres % e irá concatenar com o restante da sua expressão SQL. Caso não seja informaro, a query terá o seguinte resultado: “ZMF_CODFAB IN ‘(‘01’, ‘02’, ‘03’)’”. O BeginSql irá considerar que o conteúdo de cCodFab é uma variável comum de caractere e não uma expressão, o que irá causar erro de execução no comando.

Boa tarde.

Giordano, obrigado pelas dicas. Funcionou perfeitamente.

Maicon, o script resultante do BEGINSQL, quando não seguidas as orientações repassadas pelo Giordano, é:

SELECT SB1.B1COD, SB1.B1_DESC, SB1.B1_GRUPO, SB1.B1_TIPO FROM SB1010 AS SB1 WHERE SB1.D_E_L_E_T = ' ' AND SB1.B1_FILIAL = '01 ' AND SB1.B1_TIPO IN '('PA','AI')'

E esse script gera a seguinte mensagem de erro ao ser executado:

Mensagem 102, Nível 15, Estado 1, Linha 1 Sintaxe incorreta próxima a '('.

Ou seja, a falha ocorre quando o compilador Sql tenta interpretar o trecho " IN '('PA','AI')' ". Seguindo as orientações do Giordano, esse mesmo trecho fica assim: " IN ('PA','AI') ".

Excelente, obrigado pela explicação. Sucesso para todos!