Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Validar registro antes de insertar (https://www.clubdelphi.com/foros/showthread.php?t=46215)

Moparova 26-07-2007 16:22:30

Validar registro antes de insertar
 
Hola a todos, estoy haciendo una aplicación para recursos humanos, trabajo con delphi 5 y sql server 2000 para la bd.

Mi pregunta es la siguiente:

Quiero validar que un registro no se duplique al capturarlo , pero no se en que evento de la tabla ponerlo, ya probe con beforeinsert, beforepost, onnewrecord , pero no funciona.

Este es mi código


with spctblCapEmp do
begin
close;
ParamByName('@Id_ControlCurso').Value:=tblCapEmpId_ControlCurso.value;
ParamByName('@Id_Emp').Value:=tblCapEmpId_Emp.value;
open;
end;
if not spctblCapEmp.eof then
raise Exception.Create('Persona ya existe en curso')

mi storeprocedure es el siguiente:

CREATE PROCEDURE spctblCapEmp
@Id_ControlCurso int,
@id_Emp int

AS
BEGIN

Select * from tblCapEmp where Id_ControlCurso =@Id_ControlCurso and id_Emp=@id_Emp
end
GO


con esto trato de evitar que por un error de captura se dupliquen personas dentro del mismo curso

Los campos de mi tabla son:

id_capEmp llave (autonumerico)
id_controlcurso (curso)
id_emp (empleado)
calificacion

En donde puedo validarlo.

Gracias a todos.

eduarcol 26-07-2007 16:40:49

Yo le dejaria ese trabajo a la base de datos, simplemente declaro una clave primaria que no acepte duplicidad, y capturo las excepciones que lanzaria la bd

Moparova 26-07-2007 16:46:08

Graciasr Eduarcol,

Entonces tu me sugieres que tenga 3 llaves, mi llave primaria es id_capemp (es autonumerica y es la llave de la tabla), entonces id_curso y id_emp tambien las pongo como llaves??????

Otra pregunta cómo captura las excepciones, en general esta, pues me mandaria un mensaje de duplicidad o lago así, no??

Gracias

eduarcol 26-07-2007 16:59:10

Pues sobre las llaves no te sabria decir como es el modelo de tu base de datos, aunque me asalta una duda, porq autonumerico si no quieres que se repita???

No se con el motor que tu utilizas con el BDE funciona asi

Código Delphi [-]
try
   Dataset.Post;
except
   on E: EDBEngineError do
      begin
         ErrorCode := E.Errors[0].ErrorCode;
         case ErrorCode of
            DBIERR_SYSFILEOPEN,
            DBIERR_SYSFILEIO,
            DBIERR_SYSCORRUPT,
            DBIERR_NOCONFIGFILE,
            DBIERR_CFGCANNOTWRITE,
            DBIERR_CFGMULTIFILE,
            DBIERR_REENTERED,
            DBIERR_CANTFINDIDAPI,
            DBIERR_CANTLOADIDAPI,
            DBIERR_CANTLOADLIBRARY,
            DBIERR_TEMPFILEERR,
            DBIERR_MULTIPLEIDAPI,
            DBIERR_SHAREDMEMCONFLICT:
               msgError( msErrorSistema + NT );
            DBIERR_LOCKED,
            DBIERR_UNLOCKFAILED,
            DBIERR_FILEBUSY,
            DBIERR_DIRBUSY,
            DBIERR_FILELOCKED,
            DBIERR_DIRLOCKED,
            DBIERR_ALREADYLOCKED,
            DBIERR_NOTLOCKED,
            DBIERR_LOCKTIMEOUT,
            DBIERR_GROUPLOCKED,
            DBIERR_LOSTTBLLOCK,
            DBIERR_LOSTEXCLACCESS,
            DBIERR_NEEDEXCLACCESS,
            DBIERR_RECGROUPCONFLICT,
            DBIERR_DEADLOCK,
            DBIERR_ACTIVETRAN,
            DBIERR_NOACTIVETRAN,
            DBIERR_RECLOCKFAILED,
            DBIERR_OPTRECLOCKFAILED,
            DBIERR_OPTRECLOCKRECDEL,
            DBIERR_ENLISTFAILED,
            DBIERR_NETFILELOCKED,
            DBIERR_NETMULTIPLE:
               msgError( msTablaBloqueada + NT );
            DBIERR_WRITEERR:        msgError(msErrordeEscritura + NT);
            DBIERR_FILECORRUPT:     msgError(msTablaCorrupta + NT);
            DBIERR_INDEXCORRUPT:    msgError(msIndiceCorrupto + NT);
            DBIERR_READERR:         msgError(msErrordeLectura + NT);
            DBIERR_DIRNOACCESS:     msgError(msSinAccesoaDirectorio + NT);
            DBIERR_FILENOACCESS:    msgError(msSinAccesoaArchivo + NT);
            DBIERR_NOMEMORY:        msgError(msSinMemoria + NT);
            DBIERR_OPENTBLLIMIT:    msgError(msMuchasTablasAbiertas + NT);
            DBIERR_NOSHAREDMEMORY:  msgError(msSinMemoriaCompartida + NT);
            DBIERR_INVALIDFILENAME: msgError(msNombreArchivoIncorrecto + NT);
            DBIERR_NOSUCHINDEX:     msgError(msNombreIndiceIncorrecto + NT);
            DBIERR_KEYVIOL:         msgError(msRegistroDuplicado + ' ' + NT);
            DBIERR_FIELDISBLANK:    msgError(msCampoenBlanco + ' ' + NT);
            DBIERR_READONLYDIR:     msgError(msDirectorioSoloLectura + ' ' + NT);
            DBIERR_READONLYFLD:     msgError(msCampoSoloLectura + ' ' + NT);
            else                    msgError(msErrorDesconocido + E.Message);
         end;
         Result := False;
      end;
end;

Seria cuestion de adaptarlo al motor

Neftali [Germán.Estévez] 26-07-2007 17:00:07

Cita:

Empezado por Moparova
Otra pregunta cómo captura las excepciones, en general esta, pues me mandaria un mensaje de duplicidad o lago así, no??

Si ya tienes clave promaria definida, como es el caso; Para que tus campos no se dupliquen debes usar índices únicos. Te harán el mismo trabajo (evitar que repitas valores); Ya que la tabla sólo puede tener una clave primaria.

Elite237 31-07-2007 21:39:18

Validar Edit
 
Yo hice algo parecido a lo que tu quieres. Lo que valide es que si la clave(ya sea empleado o curso) se repetia entonces que me mandara un mensaje de que ya existe esa clave, a mi parecer, es mejor que le crees una clave a tu empleado y a tus cursos, puesto que los nombre de empleados se repetiran y tambien de los cursos pero los que los diferenciara sera tu clave.Espero y me haya explicado.El codigo que le introduci fue el siguiente

Código:

procedure TForm3.Button1Click(Sender: TObject);
begin
  if curso.Locate('Folio',edit1.Text,[]) then
  begin
    Edit1.Clear;
    mensaje:=Application.MessageBox('El numero de folio ya existe','Error de entrada')
  end
    else
  begin
  curso.Insert;
  curso.FieldValues['Nombre_curso']:=Edit1.Text;
  curso.FieldValues['Clave_CT']:=ComboBox1.Text;
  curso.FieldValues['Capacidad']:=ComboBox19.Text;
  curso.FieldValues['Tipo_curso']:=ComboBox2.Text;
  curso.FieldValues['Especialidad']:=Edit3.Text;
  curso.FieldValues['Tipo_proveedor']:=ComboBox3.Text;
  curso.FieldValues['Nivel_capacitacion']:=ComboBox4.Text;
  curso.FieldValues['Subprograma']:=ComboBox5.Text;
  curso.FieldValues['Proceso']:=ComboBox6.Text;
  curso.FieldValues['Subproceso']:=ComboBox7.Text;
  curso.FieldValues['Area_formacion']:=ComboBox8.Text;
  curso.FieldValues['Tipo_informacion']:=ComboBox9.Text;
  curso.FieldValues['Grupo_eventos']:=ComboBox10.Text;
  curso.FieldValues['Fecha_inicio']:=DateTimePicker1.Time;
  curso.FieldValues['Lugar_imparticion']:=ComboBox11.Text;
  curso.FieldValues['Duracion_dias']:=Edit4.Text;
  curso.FieldValues['Duracion_horas']:=Edit5.Text;
  curso.FieldValues['Frecuencia']:=ComboBox12.Text;
  curso.FieldValues['Horario']:=ComboBox13.Text;
  curso.FieldValues['Costo']:=Edit6.Text;
  curso.FieldValues['Renglon_gasto']:=ComboBox14.Text;
  curso.FieldValues['Concepto']:=ComboBox16.Text;
  curso.FieldValues['Instructor_I']:=ComboBox15.Text;
  curso.FieldValues['Instructor_E']:=ComboBox17.Text;
  curso.FieldValues['Folio']:=Edit7.Text;
  curso.Post;
  Edit1.Clear;
  Edit2.Clear;
  Edit3.Clear;
  Edit4.Clear;
  Edit5.Clear;
  Edit6.Clear;
  Edit7.Clear;
  ComboBox1.Clear;
  ComboBox2.Clear;
  ComboBox3.Clear;
  ComboBox4.Clear;
  ComboBox5.Clear;
  ComboBox6.Clear;
  ComboBox7.Clear;
  ComboBox8.Clear;
  ComboBox9.Clear;
  ComboBox10.Clear;
  ComboBox11.Clear;
  ComboBox12.Clear;
  ComboBox13.Clear;
  ComboBox14.Clear;
  ComboBox15.Clear;
  ComboBox16.Clear;
  ComboBox17.Clear;
  mensaje:=Application.MessageBox('Los datos se guardaron con éxito!','Mensaje de Confirmación');
end;
end;


eduarcol 31-07-2007 22:01:38

Vas bien Elite, estas aprendiendo rapido, esto lo digo porq apenas hace dias estabas liado, pero ya vas encaminado.

una simple sugerencia, realizar un locate no es recomendable si el sistema piensa ser escalable porq no hace falta recorrer los registros, solo capturar la excepcion debe ser suficiente, asi no saturamos la red

jefferson 29-10-2008 18:09:25

asi lo haria
 
hala pana.
en estos dias tenia problemas paresidos al que planteas.

y lo que hice en compañia de mis amigos fue:
hacer un procedimiento igual al insertar con la mismas condicion para poder insertar, pero con otra variable.

y en el bonton de insertar se pone una condicion que no permita que la insercion sea igual a la que ya este, en este caso seria el nombre.

ejemplo:

Código Delphi [-]
procedure TFrmcamaradecomercio.bibinsertarClick(Sender: TObject);
var
corrovorar:string;
begin
 corrovorar:=Ednombre.Text;
 pos:=empresa.repetirDato(corrovorar);
if pos>0 then
begin
    empresa.insertar(Ednombre.Text,EdNit.Text,EdPropietario.Text,EdDireccion.Text,EdTelefono.Text);
    biblimpiarclick(sender);
 end
 else
    ShowMessage('este arreglo ya esxiste');
end;


sin olvidar que antes se debe hacer el procedimiento para insertar, (preferiblemente en una unidad de codigo aparte), al igual que la incersion de validad que es = solo con otra variable.

saludos.

Neftali [Germán.Estévez] 30-10-2008 09:49:05

jefferson utiliza TAG's cuando escribas código delphi, por favor. Este se vuelve más legible.

Delphius 30-10-2008 14:35:50

Como agregado, a lo que se ha dicho, a lo que apunta el compañero eduarcol es a que no es necesario un select, ni locate. Todo apunta a capturar la excepción adecuada.
Si se ha diseñado la tabla para que tenga un campo clave único, la base de datos nos puede advertir de cualquier intento de ingresar una clave repetida. ¿Para que darle el gusto de buscar si la misma base de datos nos va a saber decir si se puede o no?;)
¿Se entiende la idea?

En vez de que viajen muchos registros por la red, sólo hacemos que viaje uno (el que deseamos insertar). Si se puede o no, ya nos dirá la base de datos.

la cosa viene a ser algo así:

Código Delphi [-]
...
try
    // aqui intentamos insertar el regitro
except
    // capturamos la excepción que nos arroja la base de datos
    // mostramos algún mensaje
end;
....

El ejemplo de eduarcol es más ilustrativo.

Saludos,

jefferson 30-10-2008 16:11:42

ok
 
Hola
Mira pana esta muy buena tu idea y es mejor que la que yo (principiante) aporté.... Pero savemos como es la programacion y que esta se presta para hacer las cosas de distintas maneras... No se nos haga raro que alguien aparesca con una solucion mas sencilla y eficas. Pero bueno para eso estamos.
gracias por el dato. bye.:)


La franja horaria es GMT +2. Ahora son las 06:14:51.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi