PDA

Ver la Versión Completa : Necesito saber el display label correcto


pani_alex
30-06-2014, 22:47:52
hola, a ver si me puedo explicar, necesito saber el display label correcto de un query, es decir si el campo se llama nombre y en el query esta escrito p.nombre (p del alias de la tabla personas) que en el display label me salga p.nombre, pues me da problemas al hacer el filtro cuando trago el nombre del campo desde el dbgridEh y hay mas de una tabla con el mismo nombre o tambien me trae el alias nombrePersona (p.nombre as nombrePersona) y no encuentra ningun campo con ese nombre.
Si no supe expresarme me lo dicen e intentare hacerlo con ejemplos graficos para darme a entender. Gracias

ecfisa
01-07-2014, 06:59:52
Hola pani_alex.

No sé si interpreté la situación, pero no debería existir conflicto si declaras diferentes alias para diferentes columnas.

Realiza la siguiente prueba donde veras listados los diferentes alias de columnas en un ListBox:

...
var
i: Integer;
begin
with TuQuery do
begin
Close;
SQL.Clear;
SQL.Add('SELECT P.ID AS P_ID, Q.ID AS Q_ID, R.ID AS R_ID,');
SQL.Add('P.NOMBRE AS P_NOMBRE, Q.NOMBRE AS Q_NOMBRE, R.NOMBRE AS R_NOMBRE');
SQL.Add('FROM TABLA1 P, TABLA2 Q, TABLA3 R'); //(*)
Open;
for i:= 0 to FieldCount-1 do
ListBox1.Items.Add(Fields[i].FieldName)
end;
...

(*) Trabaja del mismo modo aplicado a una sola tabla:

....
SQL.Add('FROM TABLA1 P, TABLA1 Q, TABLA1 R');
...

Claro está que los alias deberán ser distintos entre sí.

Saludos :)

pani_alex
01-07-2014, 15:55:40
gracias por la respuesta.

Hasta alli todo bien pero luego uso los eventos on click de la grilla segun sobre que columna uno este posicionado y modifico el query para crear filtros (en ejecucion por medio de unos procedimientos/funciones que cree), alli comienzan los errores pues "P_ID" por ejemplo no es un campo de ninguna tabla, para poder filtar por ese campo en el query tendria q pasarle el dato "P.ID" y tampoco puedo pasarle solo "ID" porque si existe otra tabla en el mismo query con el mismo nombre el filtro queda sin efecto.
Ahora en el clientDataSet teniendo todos los campos, me posiciono en uno de ellos, por ej "P_ID" que es el FielName, en el DisplayLabel tambien me carga el mismo texto pero si manualmente coloco "P.ID" todo va sobre ruedas, no hay error en nada y los filtros son aplicados sin problemas. Abria alguna forma de cargar correctamente el DisplayLabel, o de alguna manera obtener el "P.ID" DE "P_ID"?

ecfisa
01-07-2014, 16:32:34
Hola pani_alex.

No me sucede eso usando alias de columnas, para salir de dudas hace una prueba similar a esta,

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var
fn: string;
begin
fn:= Column.FieldName;
with IBQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('SELECT T1.NOMBRE AS T1_NOMBRE, T2.NOMBRE AS T2_NOMBRE');
SQL.Add('FROM TABLA T1, TABLA T2');
SQL.Add('ORDER BY ' + fn);
Open;
end;
end;

en mi caso ordena correctamente de acuerdo al alias de la columna seleccionada.

Saludos :)

pani_alex
02-07-2014, 15:45:29
Me da column unknown, solo si uso "T1.NOMBRE" funciona, tampoco son "NOMBRE" solo si es q dos tablas tienen el mismo nombre de campo

ecfisa
02-07-2014, 18:13:07
Hola pani_alex.

Me parece que es una cuestión de sintáxis relacionada con el tipo de componente y base de datos que estas usando.
Entonces la pregunta, ¿ Que gestor de base de datos y que componentes de conexión para conectarte a ella estas usando ?

Saludos :)

pani_alex
02-07-2014, 18:26:36
Pensando un poco lo q quiero se podria llamar "como obtener el campo de un alias y el alias de la tabla de un campo", lo del campo de un alias calculo se podria sacar simplemente analizando el texto sql, creo q hare la funcion, pero como podria saber por ej:
select t1.*, t2.*
from tabla1 t1, tabla2 t2
donde t1 tiene el campo nombre y t2 tambien, "nombre" de que tabla... creo q tengo una idea de como hacerlo, voy a trabajar en ello

ecfisa
02-07-2014, 18:32:04
Hola pani_alex.

Como te comenté la sintáxis puede variar levemente de acuerdo a los componentes de conexión/gestor que estés usando, si no das mas información...


Saludos :)

pani_alex
02-07-2014, 22:01:00
dbExpress
sqlConnection->SqlQuery->DataSetProvider->ClientDataSet->DataSource->dbGrithEh

base de datos firebird 2.5 dialecto 1

pero las pruebas tambien las hago en el flamerobin

ecfisa
03-07-2014, 00:22:17
Hola pani_alex.

Acabo de reproducir el caso a excepción del componente dbGrithEh que no uso. Es decir: SQLConnection -> SQLQuery -> DataSetProvider -> ClientDataSet -> DataSource -> DbGrid.

Te pongo la prueba que hice y me funciona correctamente en Firebird 2.5:

...
var
ASCDESC :Boolean = True;

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
const
ORDEN : array[Boolean] of string = ('ASC', 'DESC');
var
fn: string;
begin
ASCDESC := not ASCDESC;
fn:= Format('%s %s',[Column.FieldName, ORDEN[ASCDESC]]);
with SQLQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('SELECT T1.NOMBRE AS T1_NOMBRE, T2.NOMBRE T2_NOMBRE');
SQL.Add('FROM TABLA1 T1,TABLA2 T2 ORDER BY ' + fn);
Open;
ClientDataSet1.Refresh;
end;
end;

espero puedas sacar algo de ella.

Tal vez el componente dbGrithEh se comporte de modo diferente que el componente por defecto de Delphi (TDBGrid).

Saludos :)

pani_alex
03-07-2014, 23:16:32
realmente no lo se pero en el flamerobin tampoco hace caso cuando no se coloca el alias delante de los campos...

dejo aqui mi primer procedimiento aparentemente funcional de lo q estaba buscando, por si a alguien le sea de probecho

procedure TModGenerico.DB_ControlaDisplayLabel(ve_SqlQyery:TSQLQuery; ve_Cds:TClientDataSet);
var x,y,x_Pos,x_ultimo,x_primero:integer;
v_campo,v_campo_buscado,v_sql,v_AliasDeTabla,strTemp:string;
procedure copia_buscado;
begin
//exit;
v_campo_buscado:=copy(v_sql,x_primero,((x_ultimo-x_primero)+1));
//busca si la palabra encontrada no es una sentencia sql
if(AnsiMatchStr(v_campo_buscado,['SELECT','END']))then begin
v_campo_buscado:='';

end;
end;
procedure saca_basura;
var xx:integer;
begin
//exit;
xx:=pos(#$A,v_sql);
while xx>0 do begin
//StringReplace(v_sql,#$A,' ',[rfReplaceAll]);
//AnsiReplaceStr(v_sql,#$A,' ');
Delete(v_sql,xx,1);
insert(' ',v_sql,xx);
//Insert();
xx:=pos(#$A,v_sql);
end;
xx:=pos(#$D,v_sql);
while xx>0 do begin
//StringReplace(v_sql,#$D,' ',[rfReplaceAll]);
AnsiReplaceStr(v_sql,#$D,' ');
Delete(v_sql,xx,1);
insert(' ',v_sql,xx);
xx:=pos(#$D,v_sql);
end;
xx:=pos(#10,v_sql);
while xx>0 do begin
//StringReplace(v_sql,#10,' ',[rfReplaceAll]);
//AnsiReplaceStr(v_sql,#10,' ');
Delete(v_sql,xx,1);
insert(' ',v_sql,xx);
xx:=pos(#10,v_sql);
end;
end;
begin
try
for x:=0 to ve_Cds.FieldCount-1 do begin
//--cerar variables
x_ultimo:=0;
x_primero:=0;
v_campo_buscado:='';
v_AliasDeTabla:='0';
//--
v_campo:=UpperCase(ve_Cds.Fields[x].FieldName);
strTemp:=v_campo;
//ve_Cds.DataSource.com
v_sql:=uppercase(ve_SqlQyery.SQL.GetText);
saca_basura;
x_Pos:=pos(v_campo,v_sql);
//busca si existe el campo dentro del texto del query, si no existe no puede ser encontrado
if(x_Pos>0)then begin
y:=x_Pos-1;
while y>0 do begin
//si hay una coma quiere decir q no es un campo alias o q no tiene alias de tabla
if{(x_Pos=(y+1))and}(v_sql[y]=',')then
Break;

//pregunta si es alias de tabla
if(v_AliasDeTabla='0')and(v_sql[y]='.')then begin
v_AliasDeTabla:='S';
end else if(v_AliasDeTabla='0')then begin
v_AliasDeTabla:='N';
end;

if(v_AliasDeTabla='S')then begin
//y:=y-1;
if(x_ultimo=0)then x_ultimo:=x_Pos+length(v_campo)-1;
//busca la primera posicion
if(x_primero=0)and(x_ultimo>0)and(v_sql[y]=' ')then begin
x_primero:=y+1;
end;
//si ya se encontro el primero y el ultimo ya esta
if(x_primero>0)and(x_ultimo>0)then begin
copia_buscado;
Break;
end;

end else begin
//buscar la ultimo posicion, el primero antes del campo
if(x_ultimo=0)and(v_sql[y]<>' ')then begin
x_ultimo:=y;
end;
//busca la primera posicion
if(x_primero=0)and(x_ultimo>0)and((v_sql[y]=' ')or(v_sql[y]=#10))then begin
x_primero:=y+1;
end;
//si ya se encontro el primero y el ultimo ya esta
if(x_primero>0)and(x_ultimo>0)then begin
copia_buscado;
Break;
end;
end;
y:=y-1;
end;// while y
if(v_campo_buscado<>'')then begin
ve_Cds.Fields[x].DisplayLabel:=v_campo_buscado;
strTemp:=strTemp+' - '+v_campo_buscado;
end;
end;// if x_pos
if(FrmPrincipal.ppt_Desarrollo_Debug)then begin
FrmPrincipal.mDesarrollo.Visible:=true;
FrmPrincipal.mDesarrollo.Lines.Add(strTemp);
end;
end// for x
except
on e:Exception do
ModPrincipal.MostrarError(Self.Name,'DB_ControlaDisplayLabel','',e.Message);
end
end;


recien hoy lo hice funcionar en lo que probe, pero tiene limitaciones, no se puede usar *, se deben escribir todos los campos y no detecta campos muy complicados, como los de los case y otros, la parte de desarrollo es solo para ver lo q hace

por dar un ejemplo, esto es lo q hace, recorre los field del clientdataset y busca en el query el campo con su alias al que pertenece y este es el resultado
ID_PERSONA - U.ID_PERSONA
ID_CAJA - U.ID_CAJA
ID_USUARIO - U.ID_USUARIO
ID_SUCURSALAGENCIA
ADMINISTRADOR - U.ADMINISTRADOR
LOGIN - U.LOGIN
DESCRIPCION - SA.DESCRIPCION
CLAVE - U.CLAVE
ROOT - U.ROOT
CORREO - U.CORREO
AUTORIZATIPOCAMBIO - U.AUTORIZATIPOCAMBIO
OMITEDECLARACIONJURADA - U.OMITEDECLARACIONJURADA
MONTOMAXIMOAUTORIZACION - U.MONTOMAXIMOAUTORIZACION
AUTORIZACLIENTE - U.AUTORIZACLIENTE
AUTORIZADOCUMENTOCLIENTE - U.AUTORIZADOCUMENTOCLIENTE
ESTADO - U.ESTADO
CODIGO - SA.CODIGO
DESSUCURSALAGENCIA - SA.DESCRIPCION
CLAVEAUTORIZACIONES - U.CLAVEAUTORIZACIONES
VARIACIONPERMITIDATIPOCAMBIO - U.VARIACIONPERMITIDATIPOCAMBIO
CODCAJA - C.CODIGO
CAJANUMERADOR
DESCAJA
AUTORIZAACTOSYDOC - U.AUTORIZAACTOSYDOC
ID_IMPRESORA - U.ID_IMPRESORA
AUTORIZAIMPRESION - U.AUTORIZAIMPRESION
MONTOVARIACIONPERMITIDA - U.MONTOVARIACIONPERMITIDA
AUTORIZAANULACION - U.AUTORIZAANULACION
AUTORIZAAPERTURA - U.AUTORIZAAPERTURA
AUTORIZACIERRE - U.AUTORIZACIERRE
AUTORIZASALDOS - U.AUTORIZASALDOS
ID_USUARIO_INSERTA - U.ID_USUARIO_INSERTA
ID_USUARIO_MODIFICA - U.ID_USUARIO_MODIFICA
FECHAALTA - U.FECHAALTA
FECHABAJA - U.FECHABAJA
AUTORIZAOTRODIA - U.AUTORIZAOTRODIA
AUTORIZAPRECIOPIZARRA - U.AUTORIZAPRECIOPIZARRA
SEMAFORO - U.SEMAFORO