none
Modificaciones en SQL SERVER Y C# RRS feed

  • Pregunta

  • Buenas tardes a todos. espero que todo este bien.

    Necesito orientación de parte de Uds. por lo que les expongo a continuación.

    tengo una pequeña aplicación que cada vez crece un poco mas, ya esta corriendo a nivel local mi aplicación es para el control de maquinaria de una PYME donde laboro.

    en principio fue pensada creada y diseñada para una obra. pero ahora debo cambiar para dos obras o tal vez para mas de dos obras.

    para ello estoy pensando en lo siguiente crear una tabla que se llame "Proyecto" por nombrarlo de alguna manera. con los campos siguientes.

    create table Proyecto
    (
    Idproyecto int primary key identity((1,1),
    NumeroProyecto varchar(10),
    NombreProyecto varchar(30)
    )
    bueno esto campos como sabran pueden ser o no ser mas campos.
    ahora la primer pregunta es la siguiente.
    como hago para identificar a los usuarios del proyecto "PROYECTO-A-01"
    Yo he pensado en agregar una columna llamada Idproyecto a todas las tablas incluida la tabla usuario.
    Por favor les pido que me ayuden con ideas para ver como encarar las modificaciones que comenzare a implementar.
    la siguiente pregunta.
    ahora en la actualidad por ejemplo tengo mi tabla equipos es una tabla donde ingreso el listado general de todos los equipos del proyecto,
    y los veo todos en su totalidad.
    PREGUNTO
    Que debo hacer para que en el proyecto de nombre "PROYECTO-B-02" (Es un proyecto muy diferente al otro que tendrá sus propios equipos y sus propios usuarios y sus propios movimientos.)
    se vean solo los equipos que tiene ese proyecto y no así todo el listado general de equipos.
    como es que debo encargar dichos cambios ya que me gustaría que con solo el login me detecte a que proyecto pertenece ese usuario y me muestre solo
    los datos de ese proyecto y no así de todos los proyectos.

    que campos debo agregar a mis tablas y que cambios mas debo tener presente a la hora de modificación.

    muchas gracias por sus sugerencias, de seguro que serán acertadas.

    Roberto
    viernes, 24 de mayo de 2019 22:56

Respuestas

  • Hola Roberto C. Melgar:

    Es una pregunta muy grande para un hilo, y para una sola respuesta, además de que nadie puede adivinar como esta normalizada tu base de datos, en virtud del escenario que has intentado mostrar con tu mensaje, y que los principios de normalización dependen de muchos factores (hasta que nivel se quiere llegar).

    Normalización

    https://platzi.com/blog/normalizar-una-base-de-datos-y-no-morir-en-el-intento/

    Pero te voy a dar algún tip, por si te ayuda.

    ¿Porque llamas a una columna numero de proyecto y le pones varchar(10)) Si quieres, que sea P-0004, creas dos columnas, numero y serie y cuando muestras los resultados es la serie, P concatenas un guión y anexándole los ceros que quieras a la izquierda, le sumas el número.

    Por muy bien que te resulte, si a una columna la llamas número, debe de contener números.

    Usuarios. Los usuarios de uno u otro proyecto, realmente la tabla es la misma, lo que se hace es se crea una tabla que nos permita realizar una relación de n-m. Muchos usuarios relacionados con muchos Proyectos. Hay varias maneras de hacer estas tablas. 

    /* Opción 1 */
    drop table if exists Proyecto;
    create table Proyecto
    (
    Idproyecto int primary key identity(1,1),
    NumeroProyecto varchar(10),
    NombreProyecto varchar(30)
    )
    Go
    drop table if exists usuario;
    Create table Usuario 
    (
    idUsuario int primary key identity(1,1),
    nombre varchar(100)
    )
    go
    
    Drop table if exists UsuarioProyecto;
    Create Table UsuarioProyecto
    (
      idUsuario int
    , idProyecto int
    , primary key (idusuario, idProyecto)
    )
    go
    /* Opción 2 */
    
    drop table if exists Proyecto;
    create table Proyecto
    (
    Idproyecto int primary key identity(1,1),
    NumeroProyecto varchar(10),
    NombreProyecto varchar(30)
    )
    Go
    drop table if exists usuario;
    Create table Usuario 
    (
    idUsuario int primary key identity(1,1),
    nombre varchar(100)
    )
    go
     
    Drop table if exists UsuarioProyecto;
    Create Table UsuarioProyecto
    (
      idUsuarioProyecto int identity(1,1) primary key
    , idUsuario int
    , idProyecto int
    )
    go
    alter table UsuarioProyecto
    add constraint fk_usuario foreign key (idUsuario) References usuario (idUsuario);
    go
    alter table Proyecto
    add constraint fk_proyecto foreign key (idProyecto) References proyecto (idProyecto)

    Para los equipos, yo diría que es exactamente lo mismo que para los usuarios.

    Sin embargo para los movimientos, puedes añadir una columna a tu tabla maestra de movimientos, que sea idProyecto. Y hacer una foreign key a Proyectos.

    El resto de preguntas, tienen una definición muy vaga, para poder darte una respuesta (en mi opinión).

    Espero te ayude en algo, lo que te he comentado.

    sábado, 25 de mayo de 2019 5:13
  • Hola Roberto:

    El usuario al proyecto, debes de poder asignarlo en cualquier momento, bien sea cuando le creas o más tarde.

    Para no asignar un usuario a dos proyectos ACTIVOS, (muy importante, porque cuando un proyecto se termine, no lo vas a borrar ~ ver Nota 1), simplemente antes de permitir asignar a un usuario a un proyecto, tienes que preguntar si ese idUsuario, esta en algún proyecto activo. Si la consulta te retorna un no, entonces le permites la asignación.

    Nota 1. Para saber si un proyecto esta en activo, puedes poner un Flag en la tabla de proyectos.

    create table Proyecto
    (
    Idproyecto int primary key identity(1,1),
    NumeroProyecto varchar(10),
    NombreProyecto varchar(30),
    Estado tinyint 
    )
    Go

    Estado es igual a 0 cuando esta activo, y mayor que 0 en cualquiera de los otros estados posibles. (Cancelado o Finalizado, o suspendido Temporalmente).

    A priori luego puedes crear una tabla 

    Create table estadosProyecto
    (
    id tinyint,
    descripcion varchar(100)
    )
    

    Retorno con el usuario justo antes de asignarle un proyecto.

    Select count(*) from 
    UsuarioProyecto up
    join Proyecto p on up.idProyecto = p.Idproyecto
    join estadosProyecto e on p.Estado = e.id
    where 
    up.idUsuario = 1 /* el usuario que voy a asignar si la cuenta es igual a 0 */
    and e.id = 0 /* el estado que considero como activo */

    La resolución de la consulta será 0 cuando no esta asignado a un proyecto activo. Por tanto puedes asignar siempre que el valor devuelto sea 0.

    Espero te ayude

    lunes, 27 de mayo de 2019 4:21
  • Hola Roberto:

    En tu script hay un pequeño error.

    alter table estadosProyecto add CONSTRAINT PK_IdEstadosProyecto primary key (id)

    La tabla estadosProyecto ya tiene primary key.

    No tienes porque trabajar con números, porque tú ya tienes valores.

    Select count(*) from 
    Usuario u 
    join UsuarioProyecto up on u.idUsuario = up.idUsuario
    join Proyecto p on up.idProyecto = p.Idproyecto
    join estadosProyecto e on p.Estado = e.IdestadosProyecto
    where 
    u.nombre = 'rmelgar'
    and e.descripcion = 'ACTIVO';
    

    O lo que realmente significa, ¿En cuántos proyectos activos, esta inscrito un usuario llamado 'rmelgar'?

    Si esta consulta te devuelve un 0, significa, que puedes asignar el usuario rmelgar a cualquier proyecto en estado activo. Si te devuelve otro número, significa que ya esta en otro proyecto.

    miércoles, 29 de mayo de 2019 4:33

Todas las respuestas

  • Hola Roberto C. Melgar:

    Es una pregunta muy grande para un hilo, y para una sola respuesta, además de que nadie puede adivinar como esta normalizada tu base de datos, en virtud del escenario que has intentado mostrar con tu mensaje, y que los principios de normalización dependen de muchos factores (hasta que nivel se quiere llegar).

    Normalización

    https://platzi.com/blog/normalizar-una-base-de-datos-y-no-morir-en-el-intento/

    Pero te voy a dar algún tip, por si te ayuda.

    ¿Porque llamas a una columna numero de proyecto y le pones varchar(10)) Si quieres, que sea P-0004, creas dos columnas, numero y serie y cuando muestras los resultados es la serie, P concatenas un guión y anexándole los ceros que quieras a la izquierda, le sumas el número.

    Por muy bien que te resulte, si a una columna la llamas número, debe de contener números.

    Usuarios. Los usuarios de uno u otro proyecto, realmente la tabla es la misma, lo que se hace es se crea una tabla que nos permita realizar una relación de n-m. Muchos usuarios relacionados con muchos Proyectos. Hay varias maneras de hacer estas tablas. 

    /* Opción 1 */
    drop table if exists Proyecto;
    create table Proyecto
    (
    Idproyecto int primary key identity(1,1),
    NumeroProyecto varchar(10),
    NombreProyecto varchar(30)
    )
    Go
    drop table if exists usuario;
    Create table Usuario 
    (
    idUsuario int primary key identity(1,1),
    nombre varchar(100)
    )
    go
    
    Drop table if exists UsuarioProyecto;
    Create Table UsuarioProyecto
    (
      idUsuario int
    , idProyecto int
    , primary key (idusuario, idProyecto)
    )
    go
    /* Opción 2 */
    
    drop table if exists Proyecto;
    create table Proyecto
    (
    Idproyecto int primary key identity(1,1),
    NumeroProyecto varchar(10),
    NombreProyecto varchar(30)
    )
    Go
    drop table if exists usuario;
    Create table Usuario 
    (
    idUsuario int primary key identity(1,1),
    nombre varchar(100)
    )
    go
     
    Drop table if exists UsuarioProyecto;
    Create Table UsuarioProyecto
    (
      idUsuarioProyecto int identity(1,1) primary key
    , idUsuario int
    , idProyecto int
    )
    go
    alter table UsuarioProyecto
    add constraint fk_usuario foreign key (idUsuario) References usuario (idUsuario);
    go
    alter table Proyecto
    add constraint fk_proyecto foreign key (idProyecto) References proyecto (idProyecto)

    Para los equipos, yo diría que es exactamente lo mismo que para los usuarios.

    Sin embargo para los movimientos, puedes añadir una columna a tu tabla maestra de movimientos, que sea idProyecto. Y hacer una foreign key a Proyectos.

    El resto de preguntas, tienen una definición muy vaga, para poder darte una respuesta (en mi opinión).

    Espero te ayude en algo, lo que te he comentado.

    sábado, 25 de mayo de 2019 5:13
  • Javi Fernández Gracias

    Interesante voy entendiendo, por favor como seria un insert para esta tabla por favor 

    Create Table UsuarioProyecto
    (
      idUsuario int
    , idProyecto int
    , primary key (idusuario, idProyecto)
    )

    Yo estaba haciendo esto lo muestro para ver si iba por lo cierto o no es como lo estoy haciendo.

    Primero agregue un campo a la tabla y al formulario con el nombre Idproyecto y en la tabla Proyecto, yo estaba pensando en que al momento de crear el usuario asignarle ya el proyecto para que estaba trabajando, pero con la idea que Ud. me da seria luego que creo mi usuario y creo sus contraseñas asignarlo a un proyecto.

    eso fue lo que entendí por favor si no es así me corrige.

    agradezco nuevamente la ayuda.

    Roberto 

     

    sábado, 25 de mayo de 2019 20:28
  • Hola Roberto:

    Esa variante te permite hacer eso. Un usuario podria estar declarado en muchos proyectos. Porque los proyectos se cierran. Y se abren otros nuevos. Y asi no tienes porque duplicar datos

    • Propuesto como respuesta Carlos_Ruiz_M lunes, 27 de mayo de 2019 14:35
    domingo, 26 de mayo de 2019 6:53
  • Estimado Javi muchas gracias.

    entonces veo que es necesaria la tabla intermedia donde yo pueda agregar los Id's tanto del Usuario como del proyecto.

    ahora como me recomienda el asignado del proyecto en que tabla me recomienda hacer el asignado del proyecto.

    lo que tengo ahora es lo siguiente como lo muestro en la imagen de mi anterior intervención 

    Primero creo el usuario con nombre y apellidos y demás campos que son necesarios y luego al posesionarme sobre la fila con un botón abro otro formulario donde me captura  el usuario seleccionado y en ese momento le doy el privilegio que va a tener dentro de mi aplicación. 

    o tal vez la pregunta o duda seria la siguiente, en que momento asigno el proyecto al usuario y cual seria mi insert para agregar el usuario.

    una duda mas con esto que estoy intentando hacer, haber como lo expongo o no deseo que un usuario del proyecto P-0001 se loguee en el proyecto P-0002 con esto lo podre hacer, era cierto esto de que es una pregunta muy grande para un hilo pero ojala puedan ayudarme.

    Javi muchas gracias de verdad por responder un día domingo muchas personas descansa ud. se da tiempo para ayudarnos.

    Roberto

    domingo, 26 de mayo de 2019 23:52
  • Hola Roberto:

    El usuario al proyecto, debes de poder asignarlo en cualquier momento, bien sea cuando le creas o más tarde.

    Para no asignar un usuario a dos proyectos ACTIVOS, (muy importante, porque cuando un proyecto se termine, no lo vas a borrar ~ ver Nota 1), simplemente antes de permitir asignar a un usuario a un proyecto, tienes que preguntar si ese idUsuario, esta en algún proyecto activo. Si la consulta te retorna un no, entonces le permites la asignación.

    Nota 1. Para saber si un proyecto esta en activo, puedes poner un Flag en la tabla de proyectos.

    create table Proyecto
    (
    Idproyecto int primary key identity(1,1),
    NumeroProyecto varchar(10),
    NombreProyecto varchar(30),
    Estado tinyint 
    )
    Go

    Estado es igual a 0 cuando esta activo, y mayor que 0 en cualquiera de los otros estados posibles. (Cancelado o Finalizado, o suspendido Temporalmente).

    A priori luego puedes crear una tabla 

    Create table estadosProyecto
    (
    id tinyint,
    descripcion varchar(100)
    )
    

    Retorno con el usuario justo antes de asignarle un proyecto.

    Select count(*) from 
    UsuarioProyecto up
    join Proyecto p on up.idProyecto = p.Idproyecto
    join estadosProyecto e on p.Estado = e.id
    where 
    up.idUsuario = 1 /* el usuario que voy a asignar si la cuenta es igual a 0 */
    and e.id = 0 /* el estado que considero como activo */

    La resolución de la consulta será 0 cuando no esta asignado a un proyecto activo. Por tanto puedes asignar siempre que el valor devuelto sea 0.

    Espero te ayude

    lunes, 27 de mayo de 2019 4:21
  • Estimado Javi muchas gracias, buenas noches

    esto fue lo que hice.

    create database PruebasUsuarioProyectos
    go
    use PruebasUsuarioProyectos
    go
    create table Proyecto
    (
    Idproyecto int primary key identity(1,1),
    NumeroProyecto varchar(10),
    NombreProyecto varchar(30),
    Estado tinyint 
    );
    go
    insert into Proyecto (NumeroProyecto,NombreProyecto,Estado) VALUES ('P-01','PROYECTO UNO',1)
    Create table Usuario 
    (
    idUsuario int primary key identity(1,1),
    nombre varchar(100)
    );
    go
    INSERT INTO Usuario(nombre) VALUES('rmelgar')
    
    Create Table UsuarioProyecto
    (
      idUsuario int, 
      idProyecto int, 
      primary key (idusuario, idProyecto)
    );
    go
    insert into UsuarioProyecto(idUsuario,idProyecto) values(1,1)
    go
    select * from UsuarioProyecto
    go
    Create table estadosProyecto
    (
    IdestadosProyecto tinyint primary key identity(1,1),
    descripcion varchar(100)
    );
    INSERT INTO estadosProyecto(descripcion) VALUES('ACTIVO')
    INSERT INTO estadosProyecto(descripcion) VALUES('Cancelado')
    INSERT INTO estadosProyecto(descripcion) VALUES('Finalizado')
    INSERT INTO estadosProyecto(descripcion) VALUES('suspendido Temporalmente')
    
    alter table estadosProyecto add CONSTRAINT PK_IdEstadosProyecto primary key (id)
    alter table proyecto add Constraint FK_Proyecto_EstadosProyecto foreign key (Estado) references estadosProyecto(IdestadosProyecto);
    
    Select count(*) from 
    UsuarioProyecto up
    join Proyecto p on up.idProyecto = p.Idproyecto
    join estadosProyecto e on p.Estado = e.IdestadosProyecto
    where 
    up.idUsuario = 1 /* el usuario que voy a asignar si la cuenta es igual a 0 */
    and e.IdestadosProyecto = 1 /* el estado que considero como activo */

    ahora hay dos cositas que no entiendo porque Cero(0) y Uno(1) cuando hago mis consultas con la ultima consulta me retorna cero aun cuando cambio el 

    e.IdestadosProyecto = 1

    por favor un poquito mas de paciencia ya estoy por entender toda la cuestión.

    muchas gracias por la colaboración 

    Roberto 

    miércoles, 29 de mayo de 2019 0:30
  • Hola Roberto:

    En tu script hay un pequeño error.

    alter table estadosProyecto add CONSTRAINT PK_IdEstadosProyecto primary key (id)

    La tabla estadosProyecto ya tiene primary key.

    No tienes porque trabajar con números, porque tú ya tienes valores.

    Select count(*) from 
    Usuario u 
    join UsuarioProyecto up on u.idUsuario = up.idUsuario
    join Proyecto p on up.idProyecto = p.Idproyecto
    join estadosProyecto e on p.Estado = e.IdestadosProyecto
    where 
    u.nombre = 'rmelgar'
    and e.descripcion = 'ACTIVO';
    

    O lo que realmente significa, ¿En cuántos proyectos activos, esta inscrito un usuario llamado 'rmelgar'?

    Si esta consulta te devuelve un 0, significa, que puedes asignar el usuario rmelgar a cualquier proyecto en estado activo. Si te devuelve otro número, significa que ya esta en otro proyecto.

    miércoles, 29 de mayo de 2019 4:33
  • Javi Fernández Muchas gracias. con esto quedó mas claro para mi.

    muchas gracias

    Roberto 

    miércoles, 29 de mayo de 2019 20:33
  • De nada
    miércoles, 29 de mayo de 2019 20:34