Por lo general, sólo necesitas el DataSource si quieres presentar los registros que devuelva el Query en controles de edición de datos (TDBEdit, TDBGrid, etc.) o para establecer una relación maestro-detalle con algún otro dataset.
La sentencia SQL, en efecto, la colocas en la propiedad SQL del Query. Esta propiedad es de tipo TStrings, o sea que puedes poner la sentencia en varias líneas.
En cuanto al uso de variables, primero que nada tienes que entender que el código delphi y el código sql son mundos aparte. El código sql lo interpreta el servidor de datos, el cuál es ajeno a tu aplicación. Tú simplemente usas delphi para mandarle sentencias a dicho servidor, pero éste no reconocerá ningún símbolo (variables, constantes, etc.) que uses en tu programa.
Lo anterior no significa que no puedas pasar valores de variables en delphi a las sentencias sql, pero observa la diferencia entre la variable X y el valor de X.
Digamos que tienes una sentencia del tipo:
Código SQL
[-]
select * from usuarios where id = 84
pero quieres poder especificar ese id según el valor de alguna variable en tu aplicación, digamos UsuarioId.
No puedes escribir la sentencia
Código SQL
[-]
select * from usuarios where id = UsuarioId
porque el servidor de datos no reconocerá el término UsuarioId. En cambio, si escribes algo como:
Código Delphi
[-]
Query1.SQL.Add('select * from usuarios where id = ' + IntToStr(UsuarioId));
delphi evaluará el valor de la variable UsuarioId (digamos que es 84), lo convertirá a una cadena (función IntToStr) y el resultado, '84', lo concatenará a la cadena 'select * from usuarios where id = '. De esta forma, el parámetro que finalmente se pasa al método Add es
Código Delphi
[-]
'select * from usuarios where id = ' + '84'
esto es,
Código Delphi
[-]
'select * from usuarios where id = 84'
que ya es entendible perfectamente para el servidor de datos.
Ahora bien, lo más recomendable para el paso de valores es el uso de parámetros. Los parámetros en un Query son indicadores especiales en el cuerpo de la sentencia que se llenan posteriormente
pero antes de la ejecución de la consulta.
Siguiendo el ejemplo anterior, puedes escribir la sentencia:
Código SQL
[-]
select * from usuarios where id = :usuario_id
en el SQL del Query. Los dos puntos que preceden al término
usuario_id, indican a la componente Query, que se trata de una parámetro cuyo valor debe proporcionarse antes de la ejecución. De no hecerlo así, la componente indicaria un error.
Para llenar el parámetro usas el método ParamByName:
Código Delphi
[-]
Query1.ParamByName('usuario_id').AsInteger := UsuarioId;
Con esto, la componente busca en la sentencia sql un parámetro llamado
usuario_id y lo sustituye por el valor que se le asigne en ParamByName; en este caso, el valor de la variable UsuarioId.
El uso de parámetros te da un código mucho más limpio que la concatenación de valores al momento de formar la sentencia sql.
// Saludos