Parâmetros e UNION / INTERSECT
Uso cotidiano de parâmetros
- Construa a query com
CreateFluentSQL(dbn…)(ouTCQ). - Obtenha o comando com
.AsString. - Use a coleção
Params(interfaceIFluentSQLParams) exposta pelo objeto de query para fazer o binding na sua camada de acesso. - Garanta que a ordem dos parâmetros ligados corresponde à ordem dos placeholders na string retornada por
.AsString.
Sem isso, o driver ou o servidor pode rejeitar a execução ou associar valores às posições erradas.
IN e NOT IN com listas (v1.0.3)
Quando você usa InValues / NotIn com TArray<String> ou TArray<Double>, a SQL gerada contém um placeholder por item da lista e Params recebe um valor por placeholder, na mesma ordem (por dialeto: nomeados :p1, :p2, … ou posicionais ?). Isso evita interpolar literais vindos de coleções.
Se você passar uma única String, o framework trata o texto como subconsulta ou expressão já entre parênteses (comportamento anterior), não como lista de valores a expandir.
Mais detalhes: Referência de API e CHANGELOG.md [1.0.3].
array of const em predicados e DML (v1.0.4)
Sobrecargas que aceitam const Args: array of const (por exemplo em Where, Having, Values, ramos de CASE/When) tratam valores escalares como parâmetros (:pN ou ? por dialeto) e preenchem Params na ordem correspondente. Strings, identificadores e operadores passados como literais dentro do array of const continuam embutidos na expressão SQL (não viram binding), alinhado à regra RN-P3 descrita no pipeline.
CaseExpr(array of const) e Column(array of const) usam SqlArrayOfConstToParameterizedSql com a coleção da query: Column desde a v1.0.6 (ESP-012, issue #25); CaseExpr desde a v1.0.7 (ESP-013, rastreio em CHANGELOG [1.0.7] — não confundir com a issue #27, hoje ESP-016), com strings no array of const ainda como literais (ADR-011). Consulte CHANGELOG.md [1.0.4], [1.0.6] e [1.0.7] e a Referência de API.
Critérios e Expression no fluente (v1.0.5)
A partir da v1.0.5 (ESP-011), quando você obtém uma expressão via Expression(string) ou Expression(array of const) a partir de TFluentSQL (ou critérios de CASE que recebem FOwner.Params), o objeto TFluentSQLCriteriaExpression fica associado à mesma coleção IFluentSQLParams da query. Com isso, encadeamentos como AndOpe / OrOpe / Ope / Fun com array of const expandem escalares para placeholders da mesma forma que em Where(array of const), respeitando ADR-011 (strings em TVarRec não viram bind automático). Se a expressão for criada fora desse contexto (sem Params), o comportamento permanece o legado com SqlParamsToStr. Ver CHANGELOG.md [1.0.5] e a issue #23; acompanhamento: #24.
UNION, UNION ALL e INTERSECT
A partir da v0.2.0, quando há parâmetros nos dois ramos de uma operação de conjunto:
- A serialização pode reindexar placeholders no ramo secundário (comportamento documentado em
FluentSQL.Serialize.pas, rotinaUnionRemapBranchSQL). - A coleção visível em
Paramspode ser uma visão mesclada (TFluentSQLMergedParamsemFluentSQL.Params.pas), refletindo a ordem final na SQL.
O que fazer na prática
- Prefira sempre a mesma versão da biblioteca em todos os módulos do seu app.
- Depois de compor
Union/UnionAll/Intersect, trateParamscomo fonte única para binding, sem presumir que é apenas a coleção do ramo principal. - Em MySQL, há suporte a placeholders
?com a mesma regra de ordem; veja testes Firebird/MySQL ligados à issue #11.
Se algo não bater
Consulte Erros comuns (secção sobre UNION/INTERSECT) e a Referência de API.