Primero que nada olvidate del programa de las bases de datos; añade un nivel adicional de complejidad ya que estas intentando entender 2 conceptos al mismo tiempo. Escribe codigo sencillo para aprender las cosas, ya luego cuando tengas que unir partes veras como aplicar y juntar todo lo aprendido
Claro el "problema" es que estas ejecutando desde el depurador
Cuando se ejecuta sin el depurador, directamente se ejecuta el codigo del except
No he encontrado en Lazarus (y me imagino que CodeTyphon es igual) la opcion "Run without debugging"
Cuando ejecutas usando el depurado integrado, este se "engancha" a tu aplicacion. Cuando se produce una excepcion, el la "atrapa" y te muestra un cartel con la excepcion en cuestion, y te permite ir a la linea de codigo en ese momento o continuar
Si pones continuar, el comportamiento es distinto dependiende de: Estoy dentro de un bloque try o no (no importa si es except o finally)
1. El caso mas sencillo, no estoy en un bloque try
procedure TForm1.Button1Click(Sender: TObject);
var
Cero: Integer;
begin
Cero := 0;
ShowMessage(FloatToStr(20 div Cero));
end;
En este simple codigo de 2 lineas, podemos dividirlo en pequeñas sentencias mas simples:
a. Guardar el valor 0 en la variable "Cero"
b. Realizar la cuenta 20 dividido valor de la variable "Cero"
c. Convertir a string el resultado de b
d. Mostrar en un dialogo el resultado de c
No hay try, por lo tanto el codigo apenas ocurre la excepcion, todo lo que "faltaba por hacer", es decir, todo lo que este debajo del punto en el cual se elevo la excepcion, nunca se ejecuta: se interrumpe la ejecucion, se muestra un mensaje de error, y se "sale" del metodo en cuestion
2. Caso try-except, vuelvo a copiar el codigo de mas arriba
procedure TForm1.Button1Click(Sender: TObject);
var
Cero: Integer;
begin
try
Cero := 0;
ShowMessage(FloatToStr(20 div Cero));
except
ShowMessage('El registro esta duplicado ');
end;
end;
En este caso podria decirse que, en esencia son los mismos 4 elementos de arriba, pero imaginate que estan entre parentesis, asi
try
(
a. Guardar el valor 0 en la variable "Cero"
b. Realizar la cuenta 20 dividido valor de la variable "Cero"
c. Convertir a string el resultado de b
d. Mostrar en un dialogo el resultado de c
)
except
Dentro del parentesis, el codigo se comporta igual. Si hay un error, se detiene la ejecucion en esa linea, se eleva la excepcion pero en este caso es capturada por el bloque del except. Es decir, el error esta, pero el programador decide hacerse cargo de el, porque esta a la espera de potenciales errores. Como la excepcion es capturada para que el programador se haga cargo, el mensaje de error "en chino mandarin y los numeros raros" no se muestra, ya que se le permite al programador "personalizar el comportamiento del programa"
Por que te hice escribir ese codigo tan bobo? Porque basicamente produce una excepcion adrede y muestra un cartel en pantalla diciendo "El registro esta duplicado". Que registro. Si nunca intente insertar nada. Si no hay base de datos ni query ni nada.
Esto lo recalco porque en tus mensajes insistis con "siempre me sale que el registro esta duplicado". No. No sabemos cual es el problema. Sabemos que es una excepcion de base de datos porque cuando te dije que imprimas el nombre de la clase de la exception dio "EZSQLExcepcion". Y simplemente quiere decir eso: Es una excepcion "generica" de base de datos.
Ahora, obviamente confunde el hecho de que aparezca un cartel que diga: "Registro duplicado. EZSQLExcepcion". Pero eso es culpa del programador que basicamente escribio este codigo, traducido en poseia
"Inserta el registro con nombre: marianito y edad: 89. Si hay algun problema imprime en pantalla que es un registro duplicado. No importa si la computadora se quedo sin memoria, si la base de datos no existe, si la tabla no existe, si hay un error en el tipo de datos, si hay un error de memoria corrupta, si fallo el disco rigido, o si el usuario no dispone de permisos escritura. Tu solo pon en pantalla para todos los casos que el registro esta duplicado"
Eso es literalmente lo que dice tu codigo. Estas disfrazando todos los problemas con "el registro esta duplicado". Y hay infinidad de excepciones que pueden ocurrir, alguna de las cuales ni se nos pasan por la cabeza en este momento
3. Caso try-finally
Una pequeña variacion del codigo anterior:
procedure TForm1.Button1Click(Sender: TObject);
var
Cero: Integer;
begin
try
Cero := 0;
ShowMessage(FloatToStr(20 div Cero));
finally
ShowMessage('El finally siempre se ejecuta');
end;
end;
El finally es una estructura bastante curiosa: siempre se ejeucta. Siempre recibe el flujo de ejecucion. Lo cual no quiere decir que se garantiza que el finally se ejecuta desde la primera hasta la ultima instruccion
En un finally basicamente colocamos codigo que queremos que se ejecute siempre: ocurran errores o no. De hecho cuando mas adelante estudies estructuras de control iterativas, veras que si dentro de un try finally pones un Break, un Continue o un Exit, el finally se ejecuta siempre
En el codigo anterior, veras una excepcion en el momento que se divide por 0, tal y como ya venia pasando. La diferencia es, que una vez que se muestra la excepcion (pones aceptar) la siguiente instruccion es "ejecuta el finally"
Si no pongo el try-finally, el cuadro que imprime "El finally siempre se ejecuta", ironicamente, es una instruccion que nunca se va a ejecutar