none
Saber si una string cumple el formato de una base de datos RRS feed

  • Pregunta

  • Estoy haciendo un proyecto de apertura e importación de archivos CSV a una base de datos, y quisiera saber el método correcto para saber si cada linea del CSV cumple los criterios de orden necesarios para poder subir el archivo a la base de datos.

    Mi código va como sigue:

    if (lineas[0] != "CLAVE,NOMBRE,FACULTAD,CARRERA,ROM,SEXO,NIVEL" && lineas[0] != "CLAVE;NOMBRE;FACULTAD;CARRERA;ROM;SEXO;NIVEL")
    {
             mensaje = "El formato y orden de los datos es incorrecto";
             return false;
    }

    Mi intención es validar el formato y orden de los datos, sin embargo, esto solo compara cadenas (que en teoría es lo que debería hacer). ¿Alguna idea de como puedo verificar el formato y orden de los datos?

    Muchas gracias.

    martes, 19 de junio de 2018 21:33

Respuestas

  • Es que si bien internamente SQL Server mantiene las columnas en un orden específico, uno puede escribir T-SQL que inserta registros con un orden de columnas completamente arbitrario.  Entonces realmente el orden es irrelevante.

    Si usted realmente quisiera, puede construir SQL dinámico a partir de la primera línea, y entonces no importará si CLAVE es la primera, cuarta o última columna en el CSV.


    Jose R. MCP
    My GIT Repositories | Mis Repositorios GIT

    miércoles, 20 de junio de 2018 1:32
    Moderador
  • Hola WalfasProject8000:

    Un ejemplo simple de lo que te indica el moderador

    create table desdeCSV (clave int, nombre varchar(10), facultad varchar(10), carrera varchar(10), rom varchar(10), sexo varchar(1), nivel int)
    go
    /* orden natural de creacion */
    insert into desdeCSV(clave, nombre, facultad, carrera, rom, sexo, nivel) values (1,'primero','fac1','car1','rom1','v',1);
    go
    /* cambiando columnas de posición */
    insert into desdeCSV(clave, facultad, carrera, rom, sexo, nivel, nombre) values (2,'fac2','car2','rom2','v',2,'segundo');
    go
    /* sin mencionar las columnas solo insertando valores */
    insert into desdeCSV select 3,'tercero','fac3','car3','rom3','h',3;
    go
    /* omitiendo una columna ya que en la definición se aceptan nulos, pero nombrando campos */
    insert into desdeCSV(clave,  facultad, carrera, rom, sexo, nivel) values (4,'fac4','car4','rom4','v',4); 
    
    go
    /*observe el valor nulo de nombre */
    select * from desdeCSV
    go
    /* sin mencionar las columnas solo omitiendo una de ellas, insertando valores */
    insert into desdeCSV select 5,'fac5','car5','rom5','h',5;
    /* al no haber indicado el nombre de columnas, se interpreta que tienen que ir en la posición adecuada y entonces no coinciden los tipos de datos.*/
    go
    
    

    Ló importante cuando valides un csv, es que los datos encajen en el tipo, Si la columna clave, por ejemplo, es int, que el dato que vayas a insertar no sea "tres mil quinientos 34"

    Un saludo

    miércoles, 20 de junio de 2018 6:26
  • Validar csv es un absoluto dolor de cabeza pero muchas veces una necesidad, dado que como apuntas lo que estás leyendo son cadenas, para resolver la validación yo creo una estructura con las validaciones posibles y luego se las aplico a cada campo, por ejemplo:

    public struct Validacion
    {
    public string Nombre;
    public Type Tipo;
    public int LongitudMaxima;
    public int ValorMinimo;
    public int ValorMaximo;
    }

    Luego necesitas un metodo para hacer las validaciones, aqui tienes la validacion de tipo y faltaría que se agreguen las otras:

    private bool EsValido(string valor, Validacion validacion)
    {
    try
    {
    Convert.ChangeType(valor, validacion.Tipo);
    }
    catch (Exception e)
    {
    return false;
    }
    //... otras validaciones
    return true;
    }

    Para procesar el archivo define todas tus validaciones y luego haz un ciclo para validar cada campo, por ejemplo:

    Validacion[] validaciones = new Validacion[7];
    validaciones[0] = new Validacion() {Nombre = "Clave", Tipo = typeof(int), ValorMaximo = 0, ValorMinimo = 1000};
    validaciones[1] = new Validacion() { Nombre = "Nombre", Tipo = typeof(string), ValorMaximo = 0, ValorMinimo =0 };

    foreach (string linea in lineas)
    {
          string[] valores = linea.Split(',');
          for(int i=0;i<valores.Length;i++)
          { 
                if (!EsValido(valores[i], validaciones[i])) return false;  //o break;
           }
    }

    miércoles, 20 de junio de 2018 7:10
  • No veo como se pueda validar el orden ya que hay varios campos presumiblemente del mismo tipo.

    CLAVE:  int

    NOMBRE: String

    FACULTAD: String

    CARRERA: String (auque podría ser int si es clave)

    ROM: ?

    SEXO:?

    NIVEL:?

    Supongamos que el 1er registro es:

    "1,'Juan','Medicina','A1','M','2'".  En este ejemplo 'Juan','Medicina','A1','M' son todos de tipo String, entonce cómo saber si están en el orden correcto? Está claro que se necesita algún otro criterio, además del tipo de datos, para determinar si el orden es correcto.

    miércoles, 20 de junio de 2018 12:31

Todas las respuestas

  • Es que si bien internamente SQL Server mantiene las columnas en un orden específico, uno puede escribir T-SQL que inserta registros con un orden de columnas completamente arbitrario.  Entonces realmente el orden es irrelevante.

    Si usted realmente quisiera, puede construir SQL dinámico a partir de la primera línea, y entonces no importará si CLAVE es la primera, cuarta o última columna en el CSV.


    Jose R. MCP
    My GIT Repositories | Mis Repositorios GIT

    miércoles, 20 de junio de 2018 1:32
    Moderador
  • Hola WalfasProject8000:

    Un ejemplo simple de lo que te indica el moderador

    create table desdeCSV (clave int, nombre varchar(10), facultad varchar(10), carrera varchar(10), rom varchar(10), sexo varchar(1), nivel int)
    go
    /* orden natural de creacion */
    insert into desdeCSV(clave, nombre, facultad, carrera, rom, sexo, nivel) values (1,'primero','fac1','car1','rom1','v',1);
    go
    /* cambiando columnas de posición */
    insert into desdeCSV(clave, facultad, carrera, rom, sexo, nivel, nombre) values (2,'fac2','car2','rom2','v',2,'segundo');
    go
    /* sin mencionar las columnas solo insertando valores */
    insert into desdeCSV select 3,'tercero','fac3','car3','rom3','h',3;
    go
    /* omitiendo una columna ya que en la definición se aceptan nulos, pero nombrando campos */
    insert into desdeCSV(clave,  facultad, carrera, rom, sexo, nivel) values (4,'fac4','car4','rom4','v',4); 
    
    go
    /*observe el valor nulo de nombre */
    select * from desdeCSV
    go
    /* sin mencionar las columnas solo omitiendo una de ellas, insertando valores */
    insert into desdeCSV select 5,'fac5','car5','rom5','h',5;
    /* al no haber indicado el nombre de columnas, se interpreta que tienen que ir en la posición adecuada y entonces no coinciden los tipos de datos.*/
    go
    
    

    Ló importante cuando valides un csv, es que los datos encajen en el tipo, Si la columna clave, por ejemplo, es int, que el dato que vayas a insertar no sea "tres mil quinientos 34"

    Un saludo

    miércoles, 20 de junio de 2018 6:26
  • Validar csv es un absoluto dolor de cabeza pero muchas veces una necesidad, dado que como apuntas lo que estás leyendo son cadenas, para resolver la validación yo creo una estructura con las validaciones posibles y luego se las aplico a cada campo, por ejemplo:

    public struct Validacion
    {
    public string Nombre;
    public Type Tipo;
    public int LongitudMaxima;
    public int ValorMinimo;
    public int ValorMaximo;
    }

    Luego necesitas un metodo para hacer las validaciones, aqui tienes la validacion de tipo y faltaría que se agreguen las otras:

    private bool EsValido(string valor, Validacion validacion)
    {
    try
    {
    Convert.ChangeType(valor, validacion.Tipo);
    }
    catch (Exception e)
    {
    return false;
    }
    //... otras validaciones
    return true;
    }

    Para procesar el archivo define todas tus validaciones y luego haz un ciclo para validar cada campo, por ejemplo:

    Validacion[] validaciones = new Validacion[7];
    validaciones[0] = new Validacion() {Nombre = "Clave", Tipo = typeof(int), ValorMaximo = 0, ValorMinimo = 1000};
    validaciones[1] = new Validacion() { Nombre = "Nombre", Tipo = typeof(string), ValorMaximo = 0, ValorMinimo =0 };

    foreach (string linea in lineas)
    {
          string[] valores = linea.Split(',');
          for(int i=0;i<valores.Length;i++)
          { 
                if (!EsValido(valores[i], validaciones[i])) return false;  //o break;
           }
    }

    miércoles, 20 de junio de 2018 7:10
  • No veo como se pueda validar el orden ya que hay varios campos presumiblemente del mismo tipo.

    CLAVE:  int

    NOMBRE: String

    FACULTAD: String

    CARRERA: String (auque podría ser int si es clave)

    ROM: ?

    SEXO:?

    NIVEL:?

    Supongamos que el 1er registro es:

    "1,'Juan','Medicina','A1','M','2'".  En este ejemplo 'Juan','Medicina','A1','M' son todos de tipo String, entonce cómo saber si están en el orden correcto? Está claro que se necesita algún otro criterio, además del tipo de datos, para determinar si el orden es correcto.

    miércoles, 20 de junio de 2018 12:31
  • Creo que tu mismo te has respondido :-) si consigues suficientes validaciones para cada campo tendrás solución, sino dependes de quien te envía el archivo. 
    miércoles, 20 de junio de 2018 13:00