Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Limites en declaración de tipos de campo (https://www.clubdelphi.com/foros/showthread.php?t=79097)

Diego827 07-06-2012 07:34:09

Limites en declaración de tipos de campo
 
Hola amigos del club. Tengo un problemilla: tengo una base de datos hecha en InterBase. Esta es bien sencilla y su trabajo es almacenar datos que varian de 0 a 35.50 no más. Sin embargo tengo el problema que de vez en cuando a los operadores se les va un teclazo y zas que ingresaron un 450! Se que esto se puede limitar colocando en el TextBox una mascará (en la propiedad EditMask). Pero mi pregunta es: ¿Es posible fijar los limites cuando se declara el campo en la base de datos?

Por ejemplo algo así como:

Código SQL [-]
CREATE TABLE EJEMPLO (
  FECHA TIMESTAMP NOT NULL,
  INGRESO DECIMAL(6, 3) >0 && <=35.50,
);

Se que es una tontería pero no se como hacerlo. Como hacer para fijar rangos de ingreso desde la base de datos?

Desde ya gracias amigos.

marcoszorrilla 07-06-2012 07:53:22

Cita:

Empezado por Diego827 (Mensaje 434515)
Hola amigos del club. Tengo un problemilla: tengo una base de datos hecha en InterBase. Esta es bien sencilla y su trabajo es almacenar datos que varian de 0 a 35.50 no más. Sin embargo tengo el problema que de vez en cuando a los operadores se les va un teclazo y zas que ingresaron un 450! Se que esto se puede limitar colocando en el TextBox una mascará (en la propiedad EditMask). Pero mi pregunta es: ¿Es posible fijar los limites cuando se declara el campo en la base de datos?

Por ejemplo algo así como:

Código SQL [-]CREATE TABLE EJEMPLO ( FECHA TIMESTAMP NOT NULL, INGRESO DECIMAL(6, 3) >0 && <=35.50, );


Se que es una tontería pero no se como hacerlo. Como hacer para fijar rangos de ingreso desde la base de datos?

Desde ya gracias amigos.

check (value > 0 and < 35.50)

Ahora no puedo comprobar la sintáxis pero es algo así.
Un Saludo.

Diego827 07-06-2012 07:54:28

(Algo curioso pero que a todos nos pasó alguna vez)
 
Saben mis queridos amigos, me tienen mal acostumbradisimo!!! jaja se los comento porque deje abierto el explorador web, y a cada rato regreso a ver si ya respondieron. La verdad, siempre me han sacado de apuros! Se por supuesto que no se tiene un Foro-Center tipo Call-center en donde esta mi apreciado Casimiro Notevi etc, esperando que un ignorante como yo postee para responder! jaja me causo gracia y quise comentarlo. Se bien que un foro es foro, no el chat de FaceBook ni mucho menos Twitter y tampoco messenger pero me causo gracia lo anterior.

Por todas las veces que me salvan el pellejo (que feo pero me cubre del frio todavia) Gracias!

Diego827 07-06-2012 07:56:29

Gracias por responder!
 
Hola marcoszorrilla, gracias por responder. Ahora busco alguna referencia.

Diego827 07-06-2012 08:09:43

Encontre esto y me parece que es lo que necesito
 
Bueno encontre esto, me dirás si es lo que yo mismo deseo y a lo que te referías:

Código SQL [-]
CREATE TABLE SALARY_HISTORY
(EMP_NO EMPNO NOT NULL,
CHANGE_DATE DATE DEFAULT 'NOW' NOT NULL,
UPDATER_ID VARCHAR(20) NOT NULL,
SH_OLD_SALARY SALARY NOT NULL,
PERCENT_CHANGE DOUBLE PRECISION DEFAULT 0 NOT NULL CHECK (PERCENT_CHANGE BETWEEN –50 AND 50),
NEW_SALARY COMPUTED BY
(OLD_SALARY + OLD_SALARY * PERCENT_CHANGE / 100),
CONSTRAINT PK_SH PRIMARY KEY (EMP_NO, CHANGE_DATE, UPDATER_ID),
FOREIGN KEY (EMP_NO) REFERENCES EMPLOYEE (EMP_NO)
ON UPDATE CASCADE
ON DELETE CASCADE);

Marqué el área que creo que me indicas arriba, esa sería la forma de declararlo? Voy a probarlo y comento!

Diego827 07-06-2012 08:35:08

Excelente marcoszorrilla!
 
Me has ayudado a resolver mi problema.

Observa:

Código SQL [-]
CREATE TABLE PRUEBA (
  FECHA TIMESTAMP NOT NULL,
  DATO DECIMAL(2, 2));


ALTER TABLE BELEN ADD PRIMARY KEY (FECHA);

ALTER TABLE BELEN ADD CHECK (NIVEL BETWEEN 0 AND 5);

Y vualla! ahora salta un mensaje diciendo que esta violando un "check". Una pregunta más: Si necesito cambiar este valor en el futuro, como seria?
Debo primero hacer algo como:

Código SQL [-]
ALTER TABLE BELEN REMOVE CHECK (NIVEL BETWEEN 0 AND 5);
ALTER TABLE BELEN ADD CHECK (NIVEL BETWEEN 0 AND 6);

o sólo con darle:

Código SQL [-]
ALTER TABLE BELEN ADD CHECK (NIVEL BETWEEN 0 AND 6);

Como sería? Busque pero no encontré nada?! Voy a intentar hacerlo y posteo...

Diego827 07-06-2012 08:45:31

No puedo modificar el check creado... (help me)
 
Hola amigos;

Bueno pues he creado con la ayuda de marcoszorrilla la famosa restricción, empero no logro modificarla y mucho menos borrarla! ya intente usar "REMOVE" en vez de "ADD" y también intenté darle:

Código SQL [-]
ALTER TABLE BELEN ADD CHECK (NIVEL BETWEEN 0 AND 6);

Como sobreescribiendo el anterior CHECK pero no me funcionó, ¿alguna idea?

Diego827 07-06-2012 08:57:15

Ya lo logré!
 
Hola amigos:

Como no todos nacemos sabiendo, logre eliminar el check de esta manera:

Primero cometia el error de ingresar el valor fuera del check.

Y este de decia:
Código:

Opèration violates CHECK constraint INTEG_10 on view or table EJEMPLO
Entonces ejecute la siguiente instrucción en SQL:

Código SQL [-]
alter table EJEMPLO 
drop constraint INTEG_10

Y listo! lo único es que no se porque Interbase asigna el "INTEG_10" y si creo otra restricción "check" crea "INTEG_11", ¿no se puede personalizar este nombre para poder borrarlo sin tener que disparar la excepción?

ecfisa 07-06-2012 16:57:30

Hola Diego.
Cita:

Interbase asigna el "INTEG_10" y si creo otra restricción "check" crea "INTEG_11", ¿no se puede personalizar este nombre para poder borrarlo sin tener que disparar la excepción?
En Firebird (y supongo que en Interbase también) podés hacer:
Código SQL [-]
ALTER TABLE EJEMPLO ADD CONSTRAINT CHECK_0_6 CHECK(NIVEL BETWEEN 0 AND 6);

De ese modo luego podrás hacer:
Código SQL [-]
ALTER TABLE EJEMPLO DROP CONSTRAINT CHECK_0_6;

Saludos.

Edito: Donde, CHECK_0_6 será el alias de la restricción.

Casimiro Notevi 07-06-2012 17:14:02

A mí me gusta hacer estas cosas mediante un dominio, ejemplo:

Código SQL [-]
create domain domSiNo smallint default 0 check (value between 0 and 1); /* 0-No, 1-Si*/


create table tbConfiguracionEmpresa ( 
    Codigo domCodigoNoNulo, 
    GuardarHistoricoApuntes domSiNo, 
    primary key (Codigo));

Diego827 07-06-2012 17:26:13

Gracias amigos, ahora veo
 
Cita:

Empezado por ecfisa (Mensaje 434567)
Hola Diego.

En Firebird (y supongo que en Interbase también) podés hacer:
Código SQL [-]
ALTER TABLE EJEMPLO ADD CONSTRAINT CHECK_0_6 CHECK(NIVEL BETWEEN 0 AND 6);

De ese modo luego podrás hacer:
Código SQL [-]
ALTER TABLE EJEMPLO DROP CONSTRAINT CHECK_0_6;

Saludos.

Edito: Donde, CHECK_0_6 será el alias de la restricción.

Voy a probar esto ecfisa, gracias por tu colaboración!

Diego827 07-06-2012 17:28:11

Gracias Casimiro
 
Cita:

Empezado por Casimiro Notevi (Mensaje 434568)
A mí me gusta hacer estas cosas mediante un dominio, ejemplo:

Código SQL [-]
create domain domSiNo smallint default 0 check (value between 0 and 1); /* 0-No, 1-Si*/


create table tbConfiguracionEmpresa ( 
    Codigo domCodigoNoNulo, 
    GuardarHistoricoApuntes domSiNo, 
    primary key (Codigo));

Gracias Casimiro, empero me nace una duda: un "domain" viene a ser algo así como un "constraint"?

Casimiro Notevi 07-06-2012 18:09:43

Un dominio es más bien como un "alias", yo solo uso dominios, nunca declaro un campo por su tipo.
Por ejemplo, puedes tener un dominio 'domicilio' del tipo varchar(32) y en los campos declaras el dominio en lugar del tipo, entonces si un día quieres cambiar a varchar(64), sólo has de cambiar el dominio y automáticamente tendrás todos los campos de todas las tablas que usen el dominio 'domicilio' cambiadas a varchar(64).
Ejemplo, te pego un trozo de un script de creación de una BD:

Código SQL [-]
set sql dialect 3; 
create database "rankings.fdb" PAGE_SIZE 8192 user "SYSDBA" password "masterkey"; 

/**/ 
create domain domCodigoNoNulo integer not null; 
create domain domNombre varchar(64) character set ISO8859_1;  /* fb < 2.1 */ 
/*create domain domNombre varchar(64) character set UTF8 collate ES_ES_CI_AI default '';*/  /* fb >= 2.1 */ 
create domain domImagen blob sub_type 0; 
create domain domFecha date; 
create domain domHora time; 
create domain domFechaHora timestamp; 
create domain domComentarios blob sub_type text; 
create domain domSiNo smallint default 0 check (value between 0 and 1); /* 0-No, 1-Si*/
create domain domEstadoUsuario smallint; /* (0.sinconfirmar,1.activo,2.baja) (sinconfirmar hasta que responda el email de confirmaciﺃ٣n de alta) */ 
create domain domPuntos integer;  /* 0,1,2,3,4,5,6,7,8,9,10 */ 
create domain domLogin varchar(32); 
create domain domContrasena varchar(64); 
create domain domDescripcion varchar(256); 
create domain domEmail varchar(48); 
create domain domWeb varchar(128); 
create domain domYear integer; 
create domain domNIF varchar(16) not null; 
create domain domIP varchar(16); 
create domain domTelefono varchar(16);
create domain domWebBrowser varchar(64);  /* navegador del usuario */
create domain domSO varchar(64); /* sistema operativo del usuario */
create domain domTitulo varchar(64); /* para título de las opiniones/comentarios */
create domain domInteger integer; 
create domain domAlias varchar(16);
create domain domCaracter varchar(1);
create domain domConcepto varchar(96);
create domain domCP varchar(5);
create domain domDescripcion varchar(256);
create domain domDireccion varchar(256);
create domain domPoblacion varchar(96); 
create domain domPorcentaje double precision;
/* 
*/ 
 
create table 
tbTIPOSPROFESIONALES  
( 
  ID          domCodigoNoNulo, 
  Nombre      domNombre,      
  primary key (ID) 
); 
 
create table 
tbPAISES 
( 
  ID          domCodigoNoNulo, 
  Nombre      domNombre, 
  primary key (ID) 
); 

create table 
tbCIUDADES 
( 
  ID          domCodigoNoNulo, 
  ID_pais     domCodigoNoNulo, 
  Nombre      domNombre, 
  primary key (ID), 
  foreign key (ID_pais) references tbPAISES(ID) 
); 
 
create table 
tbESPECIALIDADES 
( 
  ID          domCodigoNoNulo, 
  Nombre      domNombre,  
  primary key (ID) 
); 
 
create table 
tbNIVELESUSUARIOS 
( 
  ID          domCodigoNoNulo, 
  Nombre      domNombre,  /* (normal,avanzado,admin,god) */ 
  primary key (ID) 
); 
   
create table 
tbAVATARES 
( 
  ID          domCodigoNoNulo, 
  Imagen      domImagen, 
  primary key (ID) 
); 
   
create table   
tbIDIOMAS 
( 
  ID        domCodigoNoNulo, 
  Idioma    domNombre,  
  primary key (ID) 
); 
 
create table 
tbPROFESIONALES 
( 
  ID                  domCodigoNoNulo, 
  ID_TipoProfesional  domCodigoNoNulo, 
  Nombre              domNombre, 
  ID_Especialidad     domCodigoNoNulo, 
  CentroTrabajo       domNombre,
  Privado             domSiNo, 
  SS                  domSiNo, 
  ID_Pais             domCodigoNoNulo, 
  ID_Ciudad           domCodigoNoNulo, 
  primary key (ID), 
  foreign key (ID_TipoProfesional) references tbTIPOSPROFESIONALES (ID), 
  foreign key (ID_Especialidad) references tbESPECIALIDADES (ID), 
  foreign key (ID_Pais) references tbPAISES (ID), 
  foreign key (ID_Ciudad) references tbCIUDADES (ID) 
); 
 
create table 
tbUSUARIOS 
( 
  ID              domCodigoNoNulo, 
  ID_NivelUsuario domCodigoNoNulo, 
  Login           domLogin,            
  Contrasena      domContrasena, 
  Nombre          domNombre, 
  Email           domEmail, 
/* [..] */     
  NIF             domNIF,   
  YearNacimiento  domYear, 
  Telefono        domTelefono, 
  ID_Avatar       domCodigoNoNulo, 
  ID_Idioma       domCodigoNoNulo, 
/* [..] */   
  ID_Pais         domCodigoNoNulo, 
  ID_Ciudad       domCodigoNoNulo, 
/* [..] */ 
  FechaHoraAlta   domFechaHora, 
  Estado          domEstadoUsuario,  /* (0.sinconfirmar,1.activo,2.baja) (sinconfirmar hasta que responda el email de confirmaciﺃ٣n de alta) */ 
/* [..] */ 
  IP              domIP,
  WebBrowser      domWebBrowser,
  SO              domSO, 
  primary key (ID), 
  foreign key (ID_NivelUsuario) references tbNIVELESUSUARIOS (ID), 
  foreign key (ID_Avatar) references tbAVATARES (ID), 
  foreign key (ID_Idioma) references tbIDIOMAS (ID), 
  foreign key (ID_Pais) references tbPAISES (ID), 
  foreign key (ID_Ciudad) references tbCIUDADES (ID)   
); 

...

Cañones 07-06-2012 21:41:11

Cita:

Empezado por Casimiro Notevi (Mensaje 434574)
Un dominio es más bien como un "alias", yo solo uso dominios, nunca declaro un campo por su tipo.
Por ejemplo, puedes tener un dominio 'domicilio' del tipo varchar(32) y en los campos declaras el dominio en lugar del tipo, entonces si un día quieres cambiar a varchar(64), sólo has de cambiar el dominio y automáticamente tendrás todos los campos de todas las tablas que usen el dominio 'domicilio' cambiadas a varchar(64).

WOW! si hubiera conocido esta práctica unos años atrás! estoy a tiempo.
Gracias.

Casimiro Notevi 07-06-2012 22:18:18

De todas formas, debes tener cuidado, por ejemplo, si tienes un campo con dominio varchar(32) y le cambias a un dominio integer, si tiene datos, firebird se quejará... y con razón :)

Diego827 08-06-2012 06:04:26

Muchas gracias por sus respuestas
 
Cita:

Empezado por Casimiro Notevi (Mensaje 434599)
De todas formas, debes tener cuidado, por ejemplo, si tienes un campo con dominio varchar(32) y le cambias a un dominio integer, si tiene datos, firebird se quejará... y con razón :)

Gracias por tu explicación Casimiro, como siempre un buen tutor; a ti por tu pronta intervención marcoszorrilla y como siempre la oportuna aparición de ecfisa.

Ok, gracias amigos quedo totalmente satisfecho con la ayuda recibida!.

Muchas gracias y hasta pronto!


La franja horaria es GMT +2. Ahora son las 02:08:03.

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