• • •

Valores Defecto/Valores NULL

💡 Tip de Arquitectura: Al centralizar la gestión de nulos en la App, eliminas el riesgo de comportamientos erráticos entre diferentes versiones de drivers de bases de datos.

La arquitectura de Excel To Database está diseñada para abstraer las particularidades de cada motor de base de datos. Mientras que los procesos ETL tradicionales suelen fallar debido a cómo cada driver (SQLClient, Oracle Data Provider, etc.) interpreta un valor nulo o una celda vacía, nuestro software unifica este comportamiento. Al gestionar los Valores por Defecto a nivel de aplicación, garantizamos que la lógica de negocio se mantenga íntegra independientemente del destino. Esto permite una portabilidad total de tus configuraciones: lo que funciona para SQL Server funcionará exactamente igual para Oracle, sin necesidad de ajustes adicionales.

Esto asegura que una celda vacía se comporte exactamente igual en SQL Server que en Oracle o MS Access, eliminando comportamientos inesperados durante la migración. Para ello se utiliza esta columna. El valor aquí introducido será utilizado en los siguientes casos:

  • Cuando una celda se encuentre vacía, ésta será interpretada como un NULL. Así, si en esta columna se introduce el valor 'NULL', esas celdas vacías se cargarán como un 'NULL'. Sin embargo, si se introduce otro valor, en la base de datos se cargará dicho valor cuando la celda esté vacía. Es el llamado 'Valor por Defecto'.
    Para campos NOT NULL, la aplicación obliga a definir un valor de sustitución. Esto actúa como un filtro de validación previo, evitando que el proceso de carga falle a mitad de ejecución y garantizando que los datos cumplan siempre con el esquema de destino.
  • Exista un error en la celda y se haya marcado la opción Sin Valores Error.

  • Exista un error de conversión de datos y se haya marcado la opción Sin Errores de Conversión.

Para introducir el valor se ha de seleccionar el contenido del TextBox y anotar el nuevo valor.

Existen un par de "tags", "Nombre Fichero" y/o "File Name", que incluidos en este campo serán sustituidos por el nombre del fichero, es decir, se empleará como valor por defecto para dicho campo el nombre del fichero del cual se están leyendo los datos.

Otro par de "tags", "Ahora" y/o "Now", permiten emplear como valor por defecto la fecha y hora actual del sistema en la que comienza la carga de datos.

En aquellos casos en que sea posible (proveedor de datos y driver adecuados), se mostrará el valor por defecto definido en la base de datos para las columnas que lo posean. Sin embargo, este dato, obtenido de la base de datos, es muy probable que deba ser modificado manualmente, ya que las expresiones indicadas en el lenguaje de la base de datos pueden no ser correctamente interpretadas por .NET.

Se recomienda encarecidamente ajustar correctamente estos valores por defecto para que se ajusten al comportamiento deseado.

MS Access: Valores Defecto/NULL

Con el fin de mostrar el comportamiento de las diferentes opciones de la aplicación, se han preparado una serie de tablas para MS Access, SQL Server y Oracle y varios Libros Excel. Los scripts de creación de tablas, los libros, las bases de datos MS Access y el fichero de Configuraciones para todos los capítulos se pueden descargar de: "Descarga de Ejemplos".
Los scripts de creación de tablas también se muestran en la documentación y, también, en la documentación se muestran las Hojas Excel utilizadas en cada momento como imágenes.

Para mostrar el comportamiento de esta opción con MS Access se utiliza la tabla cuyo script de creación se muestra a continuación y la Hoja Excel de la figura siguiente:

Option Compare Database
Option Explicit

Public Sub CreaTablaValoresDefecto()
On Error Resume Next

  CurrentProject.Connection.Execute "DROP TABLE [Tabla Valores Defecto]"

On Error GoTo Sub_Err

  CurrentProject.Connection.Execute "CREATE TABLE [Tabla Valores Defecto](" & _
    "[Id] COUNTER NOT NULL, " & _
    "[Proveedor Datos] TEXT (255) NOT NULL, " & _
    "[Driver] TEXT (255) NOT NULL, " & _
    "[Texto 5 N Null N Empty Def Val] TEXT (5) NOT NULL, " & _
    "[Byte N Null Def Val] BYTE NOT NULL, " & _
    "[Fecha/Hora N Null Def Val] DATETIME NOT NULL, " & _
    "[Sí/No Def True] YESNO" & _
  ")"

  Dim db As Object, tbl As Object, fld As Object

  Set db = CurrentDb
  db.TableDefs.Refresh
  Set tbl = db.TableDefs("Tabla Valores Defecto")
  tbl.Fields.Refresh
  Set fld = tbl.Fields("Proveedor Datos")
  fld.AllowZeroLength = False
  fld.Properties.Append fld.CreateProperty("UnicodeCompression", 1, True)
  Set fld = tbl.Fields("Driver")
  fld.AllowZeroLength = False
  fld.Properties.Append fld.CreateProperty("UnicodeCompression", 1, True)

  Set fld = tbl.Fields("Texto 5 N Null N Empty Def Val")
  fld.Properties.Append fld.CreateProperty("UnicodeCompression", 1, True)
  fld.AllowZeroLength = False
  fld.DefaultValue = "V. D."
  Set fld = tbl.Fields("Byte N Null Def Val")
  fld.DefaultValue = "255"
  Set fld = tbl.Fields("Fecha/Hora N Null Def Val")
  fld.DefaultValue = "=CDate(""15/01/2023"")"
  Set fld = tbl.Fields("Sí/No Def True")
  fld.DefaultValue = "Yes"

  CurrentProject.Connection.Execute "CREATE UNIQUE INDEX PrimaryKey ON [Tabla Valores Defecto] (Id ASC) WITH PRIMARY"

Sub_Exit:
  Set fld = Nothing
  Set tbl = Nothing
  If Not db Is Nothing Then db.Close
  Set db = Nothing
  Exit Sub
  
Sub_Err:
  MsgBox "Se ha producido un error en 'CreaTablaValoresDefecto'." & vbNewLine & vbNewLine & vbTab & Err.Description, , "Error Nº: " & Err.Number
  Resume Sub_Exit
  Resume
End Sub

MS Access: Hoja Excel para [Tabla Valores Defecto]

MS Access: Hoja Excel para [Tabla Valores Defecto]

Resaltar que este dato (el valor por defecto de una columna definido en la base de datos MS Access) se puede obtener con conexiones OLE DB, pero NO con conexiones ODBC, ya que para estas últimas el proveedor de datos no ofrece esa posibilidad. Así, en la figura siguiente se muestra el "Panel de Mapeos" para una conexión OLE DB.

MS Access: Panel de Mapeos con Valores Defecto/NULL

MS Access: Panel de Mapeos con Valores Defecto/NULL con conexión OLE DB.

  • MS Access: Valores Defecto/NULL. Campos que no admiten Null (NOT NULL)

    Cuando un campo es requerido (por ejemplo: "[Byte N Null Def Val] BYTE NOT NULL" y no se define este valor para dicho campo (NULL en lugar de 255 como se muestra en la figura anterior), se producirá un error durante la fase de carga de datos. El error mostrado en los ficheros de _Error.log será similar al siguiente:

    Conexiones OLE DB
    Fila: 1
    Comando: INSERT INTO [Tabla Valores Defecto] ([Sí/No Def True], [Fecha/Hora N Null Def Val], [Byte N Null Def Val], [Texto 5 N Null N Empty Def Val], [Driver], [Proveedor Datos]) VALUES (?, ?, ?, ?, ?, ?)
    Comando Select: SELECT [Sí/No Def True], [Fecha/Hora N Null Def Val], [Byte N Null Def Val], [Texto 5 N Null N Empty Def Val], [Driver], [Proveedor Datos] FROM [Tabla Valores Defecto]
    Excepción:
    {
      "$id": "1",
      "$type": "System.Data.OleDb.OleDbException, System.Data",
      "ErrorCode": -2147467259,
      "Errors": {
        "$type": "System.Data.OleDb.OleDbErrorCollection, System.Data",
        "$values": [
          {
            "$id": "2",
            "$type": "System.Data.OleDb.OleDbError, System.Data",
            "Message": "You must enter a value in the 'Tabla Valores Defecto.Byte N Null Def Val' field.",
            "NativeError": -541331061,
            "Source": "Microsoft Access Database Engine",
            "SQLState": "3314"
          }
        ]
      },
      "Message": "You must enter a value in the 'Tabla Valores Defecto.Byte N Null Def Val' field.",
      "Data": {
        "$type": "System.Collections.ListDictionaryInternal, mscorlib"
      },
      "InnerException": null,
      "HelpLink": null,
      "Source": "Microsoft Access Database Engine",
      "HResult": -2147467259
    }
    
        Columna: Sí/No Def True    Valor: True
        Columna: Fecha/Hora N Null Def Val    Valor: 01/15/2023 00:00:00
        Columna: Byte N Null Def Val    Valor: 
        Columna: Texto 5 N Null N Empty Def Val    Valor: V. D.
        Columna: Driver    Valor: Microsoft.ACE.OLEDB.16.0
        Columna: Proveedor Datos    Valor: OLE DB
    Se ha producido una excepción al intentar cargar la Tabla 'Tabla Valores Defecto'. Error en la Fila: 1
        Query que indica las columnas utilizadas de la Tabla:
        SELECT [Sí/No Def True], [Fecha/Hora N Null Def Val], [Byte N Null Def Val], [Texto 5 N Null N Empty Def Val], [Driver], [Proveedor Datos] FROM [Tabla Valores Defecto]
    {
      "$id": "1",
      "$type": "System.Data.OleDb.OleDbException, System.Data",
      "ErrorCode": -2147467259,
      "Errors": {
        "$type": "System.Data.OleDb.OleDbErrorCollection, System.Data",
        "$values": [
          {
            "$id": "2",
            "$type": "System.Data.OleDb.OleDbError, System.Data",
            "Message": "You must enter a value in the 'Tabla Valores Defecto.Byte N Null Def Val' field.",
            "NativeError": -541331061,
            "Source": "Microsoft Access Database Engine",
            "SQLState": "3314"
          }
        ]
      },
      "Message": "You must enter a value in the 'Tabla Valores Defecto.Byte N Null Def Val' field.",
      "Data": {
        "$type": "System.Collections.ListDictionaryInternal, mscorlib"
      },
      "InnerException": null,
      "HelpLink": null,
      "Source": "Microsoft Access Database Engine",
      "HResult": -2147467259
    }
    
    Nº Filas insertadas: 0
    
    
    
    Conexiones ODBC
    Fila: 1
    Comando: INSERT INTO [Tabla Valores Defecto] ([Sí/No Def True], [Fecha/Hora N Null Def Val], [Byte N Null Def Val], [Texto 5 N Null N Empty Def Val], [Driver], [Proveedor Datos]) VALUES (?, ?, ?, ?, ?, ?)
    Comando Select: SELECT [Sí/No Def True], [Fecha/Hora N Null Def Val], [Byte N Null Def Val], [Texto 5 N Null N Empty Def Val], [Driver], [Proveedor Datos] FROM [Tabla Valores Defecto]
    Excepción:
    {
      "$id": "1",
      "$type": "System.Data.Odbc.OdbcException, System.Data",
      "Errors": {
        "$type": "System.Data.Odbc.OdbcErrorCollection, System.Data",
        "$values": [
          {
            "$id": "2",
            "$type": "System.Data.Odbc.OdbcError, System.Data",
            "Message": "[Microsoft][ODBC Microsoft Access Driver] You must enter a value in the 'Tabla Valores Defecto.Byte N Null Def Val' field.",
            "SQLState": "HY000",
            "NativeError": -3701,
            "Source": "ACEODBC.DLL"
          }
        ]
      },
      "Source": "ACEODBC.DLL",
      "ErrorCode": -2146232009,
      "Message": "ERROR [HY000] [Microsoft][ODBC Microsoft Access Driver] You must enter a value in the 'Tabla Valores Defecto.Byte N Null Def Val' field.",
      "Data": {
        "$type": "System.Collections.ListDictionaryInternal, mscorlib"
      },
      "InnerException": null,
      "HelpLink": null,
      "HResult": -2146232009
    }
    
        Columna: Sí/No Def True    Valor: True
        Columna: Fecha/Hora N Null Def Val    Valor: 01/15/2023 00:00:00
        Columna: Byte N Null Def Val    Valor: 
        Columna: Texto 5 N Null N Empty Def Val    Valor: V. D.
        Columna: Driver    Valor: Microsoft Access Driver (*.mdb, *.accdb)
        Columna: Proveedor Datos    Valor: ODBC
    Se ha producido una excepción al intentar cargar la Tabla 'Tabla Valores Defecto'. Error en la Fila: 1
        Query que indica las columnas utilizadas de la Tabla:
        SELECT [Sí/No Def True], [Fecha/Hora N Null Def Val], [Byte N Null Def Val], [Texto 5 N Null N Empty Def Val], [Driver], [Proveedor Datos] FROM [Tabla Valores Defecto]
    {
      "$id": "1",
      "$type": "System.Data.Odbc.OdbcException, System.Data",
      "Errors": {
        "$type": "System.Data.Odbc.OdbcErrorCollection, System.Data",
        "$values": [
          {
            "$id": "2",
            "$type": "System.Data.Odbc.OdbcError, System.Data",
            "Message": "[Microsoft][ODBC Microsoft Access Driver] You must enter a value in the 'Tabla Valores Defecto.Byte N Null Def Val' field.",
            "SQLState": "HY000",
            "NativeError": -3701,
            "Source": "ACEODBC.DLL"
          }
        ]
      },
      "Source": "ACEODBC.DLL",
      "ErrorCode": -2146232009,
      "Message": "ERROR [HY000] [Microsoft][ODBC Microsoft Access Driver] You must enter a value in the 'Tabla Valores Defecto.Byte N Null Def Val' field.",
      "Data": {
        "$type": "System.Collections.ListDictionaryInternal, mscorlib"
      },
      "InnerException": null,
      "HelpLink": null,
      "HResult": -2146232009
    }
    
    Nº Filas insertadas: 0
    
  • MS Access: Valores Defecto/NULL. Valores defecto y .NET

    Los valores por defecto para los campos de tipo texto es posible que estén encerrados entre comillas dobles o simples, las cuales son añadidas por el driver OLE DB para MS Access. Esto hace, por ejemplo, que para el campo "Texto 5 N Null N Empty Def Val" se le asigne el valor por defecto "V. D." con comillas dobles incluidas. La solución es evidente: eliminar las comillas dobles.
    Téngase en cuenta que, si se marca la opción Truncar Cadenas, ésta truncará el valor por defecto, quedando éste como '"V. D' (comillas simples no incluidas). Este echo es informado por la aplicación con el siguiente mensaje:

    Celda: , Valor: "V. D.", Tabla: Tabla Valores Defecto, Columna: Texto 5 N Null N Empty Def Val, Nº Máx caracteres permitidos: 5
        Opción "Truncar Cadenas" marcada. Valor Truncado: "V. D
    

    Para el campo "Fecha/Hora N Null Def Val" se obtiene como valor por defecto "=CDate("15/01/2023")", el cual no es un valor o expresión que .NET pueda interpretar correctamente. La solución, para este caso, pasaría por introducir la fecha directamente como valor por defecto: 15/01/2023

    El campo "Sí/No Def True" en MS Access (español) tiene definido como valor por defecto "Sí" ("Yes" en inglés). Las conexiones OLE DB obtienen este valor, y al proceder a la comprobación de la configuración se produce un error porque .NET no es capaz de interpretar dicho dato correctamente.

    Panel de Resultados
    
            Hoja 'MS Access - Val Def-Val Null': Comprobando ...
    
    Celda: , Valor: Yes, Tabla: Tabla Valores Defecto, Columna: Sí/No Def True
        El contenido de la Celda no ha podido convertirse al tipo de datos Boolean
    
    El valor por defecto 'Yes' indicado para la Columna 'Sí/No Def True'
    no puede ser convertido al tipo de datos de la columna.
    
    No se puede reconocer la cadena como un tipo booleano válido.
    
    
            Hoja 'MS Access - Val Def-Val Null': Comprobación Finalizada. Con modificaciones o fallos.
    
    Fichero "Excel To Database_Error_MS_Access_OLE_DB.log"
    
            Hoja 'MS Access - Val Def-Val Null': Comprobando ...
    
    Celda: , Valor: Yes, Tabla: Tabla Valores Defecto, Columna: Sí/No Def True
        El contenido de la Celda no ha podido convertirse al tipo de datos Boolean
    
    El valor por defecto 'Yes' indicado para la Columna 'Sí/No Def True'
    no puede ser convertido al tipo de datos de la columna.
    
    {
      "$id": "1",
      "$type": "System.FormatException, mscorlib",
      "Message": "No se puede reconocer la cadena como un tipo booleano válido.",
      "Data": {
        "$type": "System.Collections.ListDictionaryInternal, mscorlib"
      },
      "InnerException": null,
      "HelpLink": null,
      "Source": "mscorlib",
      "HResult": -2146233033
    }
    
            Hoja 'MS Access - Val Def-Val Null': Comprobación Finalizada. Con modificaciones o fallos.
    

    El problema, en este caso, se resuelve sustituyendo el valor de "Yes" por "true", ya que .NET sí es capaz de procesar este valor.

  • MS Access: Valores Defecto/NULL. Campos Booleanos

    Un caso especial es el comportamiento de los campos de tipo Sí/No (Booleanos) en MS Access. Este tipo de datos es siempre requerido, es decir, no admiten NULL. En las conexiones ODBC es necesario definir un valor por defecto, ya que en caso contrario la fase de comprobación de la configuración finalizará con un error y se mostrará el siguiente mensaje:

    Conexiones ODBC
            Hoja 'MS Access - Val Def-Val Null': Comprobando ...
    
    La columna "Sí/No Def True" de la tabla "Tabla Valores Defecto" no admite valores nulos.
    Por favor, indique un valor por defecto distinto de nulo para la columna
            Hoja 'MS Access - Val Def-Val Null': Comprobación Finalizada. Con modificaciones o fallos.
    

    Sin embargo, las conexiones OLE DB tienen un comportamiento totalmente diferente. Al definir como valor por defecto NULL, por una extraña razón ese NULL es sustituido por el valor por defecto que admiten las variables de .NET para el tipo de datos "bool": false. Y es ese dato es el que se insertará en el campo, aunque en la Base de Datos el campo tenga definido como valor por defecto "true".

SQL Server: Valores Defecto/NULL

Para mostrar el comportamiento de esta opción con SQL Server se utiliza la tabla definida anteriormente en el apartado Opciones de Carga de Hoja. También se utiliza el Libro Excel indicado en dicho apartado, el cual contiene la Hoja mostrada en la siguiente figura que es la utilizada en este apartado.

SQL Server: Hoja Excel para [Tabla Interfaz Usuario]

SQL Server: Hoja Excel para [Tabla Interfaz Usuario]

Los valores por defecto definidos en la base de datos son obtenidos con cualquier driver de los permitidos en Excel To Database ya que es precisamente la aplicación quién los obtiene, no los drivers.

SQL Server: Panel de Mapeos con Valores Defecto/NULL

SQL Server: Panel de Mapeos con Valores Defecto/NULL.

  • SQL Server: Valores Defecto/NULL. Campos que no admiten Null (NOT NULL)

    Cuando un campo es requerido (por ejemplo: "[Char5 N Null] [char](5) COLLATE Modern_Spanish_100_CS_AS NOT NULL" y no se define este valor para dicho campo, se producirá un error durante la fase de comprobación de la configuración. El error mostrado tanto en pantalla como en los ficheros de _Error.log será similar al siguiente:

    La columna "Char5 N Null" de la tabla "dbo.Tabla Interfaz Usuario" no admite valores nulos.
    Por favor, indique un valor por defecto distinto de nulo para la columna
    
  • SQL Server: Valores Defecto/NULL. Valores defecto y .NET

    En el Panel de Mapeos se observa que los valores por defecto están encerrados entre paréntesis y, en el caso de las cadenas de caracteres además incluyen unas comillas simples. Esto hace, por ejemplo, que para el campo "Char5 N Null Def Val" se le asigne el valor por defecto "('V. D.')" sin las comillas dobles, y, que, por tanto, se supere la longitud máxima del campo de 5 caracteres. La solución es evidente: eliminar los paréntesis y las comillas simples.
    Si la opción Truncar Cadenas se encuentra marcada, ésta truncará el valor por defecto, quedando éste como "('V. " (comillas dobles no incluidas).

    Volver a destacar que el valor por defecto obtenido de la base de datos es muy probable que deba ser modificado manualmente, ya que las expresiones indicadas en el lenguaje de la base de datos pueden no ser correctamente interpretadas por .NET. Así, para el campo "DateTime" se obtiene "(getdate())" (sin las comillas dobles). En la figura siguiente se muestra dicho hecho y se indican los formatos admitidos por la aplicación para las fechas (que suelen ser dependientes de la configuración del sistema).

    SQL Server: Error al convertir una fecha

    SQL Server: Error al convertir una fecha.

    Tras finalizar la fase de comprobación de la Configuración, durante la fase de carga de datos se producirá un error al intentar cargar un NULL en dicha columna. En los ficheros de _Error.log aparecerán mensajes similares a los siguientes:

    Conexiones .NET (System.Data.SqlClient)
    
    Se ha producido una excepción durante la carga de datos en la Tabla 'dbo.Tabla Interfaz Usuario'.
        Query que indica las columnas utilizadas de la Tabla:
        SELECT [DateTime], [SmallMoney], [SmallInt], [Char5UTF8], [Char5 N Null Def Val], [Char5 N Null], [Char5] FROM [dbo].[Tabla Interfaz Usuario]
    {
      "$id": "1",
      "$type": "System.InvalidOperationException, mscorlib",
      "Message": "El valor del tipo especificado String del origen de datos no se puede convertir al tipo datetime de la columna de destino especificada.",
      "Data": {
        "$type": "System.Collections.ListDictionaryInternal, mscorlib"
      },
      "InnerException": {
        "$type": "System.FormatException, mscorlib",
        "Message": "Error al convertir el valor del parámetro de String a DateTime.",
        "Data": {
          "$type": "System.Collections.ListDictionaryInternal, mscorlib"
        },
        "InnerException": {
          "$type": "System.FormatException, mscorlib",
          "Message": "No se puede reconocer la cadena como valor DateTime válido. Hay una palabra desconocida a partir del índice 0.",
          "Data": {
            "$type": "System.Collections.ListDictionaryInternal, mscorlib"
          },
          "InnerException": null,
          "HelpLink": null,
          "Source": "mscorlib",
          "HResult": -2146233033
        },
        "HelpLink": null,
        "Source": "System.Data",
        "HResult": -2146233033
      },
      "HelpLink": null,
      "Source": "System.Data",
      "HResult": -2146233079
    }
    
    
    Conexiones OLE DB (MSOLEDBSQL19)
    
    Fila: 1
    Comando: INSERT INTO [RepositorioLicencias5].[dbo].[Tabla Interfaz Usuario] ([DateTime], [SmallMoney], [SmallInt], [Char5UTF8], [Char5 N Null Def Val], [Char5 N Null], [Char5]) VALUES (?, ?, ?, ?, ?, ?, ?)
    Comando Select: SELECT [DateTime], [SmallMoney], [SmallInt], [Char5UTF8], [Char5 N Null Def Val], [Char5 N Null], [Char5] FROM [dbo].[Tabla Interfaz Usuario]
    Excepción:
    {
      "$id": "1",
      "$type": "System.FormatException, mscorlib",
      "Message": "Error al convertir el valor del parámetro de String a DateTime.",
      "Data": {
        "$type": "System.Collections.ListDictionaryInternal, mscorlib"
      },
      "InnerException": {
        "$type": "System.FormatException, mscorlib",
        "Message": "No se puede reconocer la cadena como valor DateTime válido.",
        "Data": {
          "$type": "System.Collections.ListDictionaryInternal, mscorlib"
        },
        "InnerException": null,
        "HelpLink": null,
        "Source": "mscorlib",
        "HResult": -2146233033
      },
      "HelpLink": null,
      "Source": "System.Data",
      "HResult": -2146233033
    }
    
        Columna: DateTime    Valor: (getdate())
        Columna: SmallMoney    Valor: 
        Columna: SmallInt    Valor: 
        Columna: Char5UTF8    Valor: 
        Columna: Char5 N Null Def Val    Valor: ('V. 
        Columna: Char5 N Null    Valor: No Nl
        Columna: Char5    Valor: a
    Se ha producido una excepción al intentar cargar la Tabla 'dbo.Tabla Interfaz Usuario'. Error en la Fila: 1
        Query que indica las columnas utilizadas de la Tabla:
        SELECT [DateTime], [SmallMoney], [SmallInt], [Char5UTF8], [Char5 N Null Def Val], [Char5 N Null], [Char5] FROM [dbo].[Tabla Interfaz Usuario]
    {
      "$id": "1",
      "$type": "System.FormatException, mscorlib",
      "Message": "Error al convertir el valor del parámetro de String a DateTime.",
      "Data": {
        "$type": "System.Collections.ListDictionaryInternal, mscorlib"
      },
      "InnerException": {
        "$type": "System.FormatException, mscorlib",
        "Message": "No se puede reconocer la cadena como valor DateTime válido.",
        "Data": {
          "$type": "System.Collections.ListDictionaryInternal, mscorlib"
        },
        "InnerException": null,
        "HelpLink": null,
        "Source": "mscorlib",
        "HResult": -2146233033
      },
      "HelpLink": null,
      "Source": "System.Data",
      "HResult": -2146233033
    }
    
    Nº Filas insertadas: 0
    
    
    Conexiones ODBC ({ODBC Driver 18 for SQL Server})
    
    Fila: 1
    Comando: INSERT INTO [RepositorioLicencias5].[dbo].[Tabla Interfaz Usuario] ([DateTime], [SmallMoney], [SmallInt], [Char5UTF8], [Char5 N Null Def Val], [Char5 N Null], [Char5]) VALUES (?, ?, ?, ?, ?, ?, ?)
    Comando Select: SELECT [DateTime], [SmallMoney], [SmallInt], [Char5UTF8], [Char5 N Null Def Val], [Char5 N Null], [Char5] FROM [dbo].[Tabla Interfaz Usuario]
    Excepción:
    {
      "$id": "1",
      "$type": "System.FormatException, mscorlib",
      "Message": "Error al convertir el valor del parámetro de String a DateTime.",
      "Data": {
        "$type": "System.Collections.ListDictionaryInternal, mscorlib"
      },
      "InnerException": {
        "$type": "System.FormatException, mscorlib",
        "Message": "No se puede reconocer la cadena como valor DateTime válido.",
        "Data": {
          "$type": "System.Collections.ListDictionaryInternal, mscorlib"
        },
        "InnerException": null,
        "HelpLink": null,
        "Source": "mscorlib",
        "HResult": -2146233033
      },
      "HelpLink": null,
      "Source": "System.Data",
      "HResult": -2146233033
    }
    
        Columna: DateTime    Valor: (getdate())
        Columna: SmallMoney    Valor: 
        Columna: SmallInt    Valor: 
        Columna: Char5UTF8    Valor: 
        Columna: Char5 N Null Def Val    Valor: ('V. 
        Columna: Char5 N Null    Valor: No Nl
        Columna: Char5    Valor: a
    Se ha producido una excepción al intentar cargar la Tabla 'dbo.Tabla Interfaz Usuario'. Error en la Fila: 1
        Query que indica las columnas utilizadas de la Tabla:
        SELECT [DateTime], [SmallMoney], [SmallInt], [Char5UTF8], [Char5 N Null Def Val], [Char5 N Null], [Char5] FROM [dbo].[Tabla Interfaz Usuario]
    {
      "$id": "1",
      "$type": "System.FormatException, mscorlib",
      "Message": "Error al convertir el valor del parámetro de String a DateTime.",
      "Data": {
        "$type": "System.Collections.ListDictionaryInternal, mscorlib"
      },
      "InnerException": {
        "$type": "System.FormatException, mscorlib",
        "Message": "No se puede reconocer la cadena como valor DateTime válido.",
        "Data": {
          "$type": "System.Collections.ListDictionaryInternal, mscorlib"
        },
        "InnerException": null,
        "HelpLink": null,
        "Source": "mscorlib",
        "HResult": -2146233033
      },
      "HelpLink": null,
      "Source": "System.Data",
      "HResult": -2146233033
    }
    
    Nº Filas insertadas: 0
    

    En este caso se propone poner como valor por defecto la palabra clave "Ahora" o "Now", la cual hace que se inserte la fecha y hora en que da comienzo la carga de datos, de forma que todos los registros insertados en la tabla que utilicen este valor por defecto tendrán el mismo dato. Se ha tomado esta decisión y no la de insertar la fecha y hora en que se inserta cada registro (que realmente es lo que hace la base de datos) por que se desea que queden marcados dichos registros como que se insertaron conjuntamente.

    Se recomienda encarecidamente ajustar correctamente estos valores por defecto para que se ajusten al comportamiento deseado.

    Por último, indicar que al contrario que sucede en MS Access, el comportamiento de los Booleans (Bit) para los valores por defecto es el mismo que para el resto de los campos numéricos.

Oracle: Valores Defecto/NULL

Para mostrar el comportamiento de esta opción con Oracle se utiliza la siguiente tabla:

CREATE TABLE "Tabla Valores Defecto" (
  Id NUMBER(6) GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  Provider                      VARCHAR2(10 CHAR) NOT NULL,
  Driver                        VARCHAR2(50 CHAR) NOT NULL,

  "Char 5"                      CHAR(5 CHAR),
  "Char 5 N Null"               CHAR(5 CHAR) NOT NULL,
  "Char 5 Val Def"              CHAR(5 CHAR) DEFAULT 'V.1D.',
  --"Char 5 Val Def"              CHAR(5 CHAR) NOT NULL DEFAULT 'V. D.',
  "Char 5 Val Def On Null"      CHAR(5 CHAR) DEFAULT ON NULL 'V. D.',
  "Int 2 N Null"                NUMBER(2) NOT NULL,
  "Int 2 Val Def"               NUMBER(2) DEFAULT -1,
  "Int 2 Val Def On Null"       NUMBER(2) DEFAULT ON NULL -1,
  "Date N Null"                 DATE NOT NULL,
  "Date Val Def"                DATE DEFAULT sysdate,
  "Date Val Def On Null"        DATE DEFAULT ON NULL date'0001-01-01'
);

Destacar que en Oracle 21 no se admite la declaración de campos con la sintaxis: "Char 5 Val Def" CHAR(5 CHAR) NOT NULL DEFAULT 'V.1D.'.

También se utiliza el Libro Excel indicado en este apartado, el cual contiene la Hoja mostrada en la siguiente figura que es la utilizada en este apartado.

Oracle: Hoja Excel para [Tabla Valores Defecto]

Oracle: Hoja Excel para [Tabla Valores Defecto]

Los valores por defecto definidos en la base de datos son obtenidos con cualquier driver de los permitidos en Excel To Database ya que es precisamente la aplicación quién los obtiene, no los drivers.

Oracle: Panel de Mapeos con Valores Defecto/NULL

Oracle: Panel de Mapeos con Valores Defecto/NULL.

  • Oracle: Valores Defecto/NULL. Campos que no admiten Null (NOT NULL)

    Cuando un campo es requerido (por ejemplo: ""Char 5 N Null" CHAR(5 CHAR) NOT NULL") y no se define este valor para dicho campo, se producirá un error durante la fase de comprobación de la Configuración. El error mostrado tanto en pantalla como en los ficheros de _Error.log será similar al siguiente:

    La columna "Char 5 N Null" de la tabla "Tabla Valores Defecto" no admite valores nulos.
    Por favor, indique un valor por defecto distinto de nulo para la columna
    
  • Oracle: Valores Defecto/NULL. Valores defecto y .NET

    En el Panel de Mapeos se observa que algunos valores por defecto están encerrados entre comillas simples. Esto hace, por ejemplo, que para el campo "Char 5 Val Def" se le asigne el valor por defecto "'V.1D.'", sin las comillas dobles, y, que, por tanto, se supere la longitud máxima del campo de 5 caracteres. La solución es evidente: eliminar las comillas simples.
    Si la opción Truncar Cadenas se encuentra marcada, ésta truncará el valor por defecto, quedando éste como "('V.1" (comillas dobles no incluidas).

    Volver a destacar que el valor por defecto obtenido de la base de datos es muy probable que deba ser modificado manualmente, ya que las expresiones indicadas en el lenguaje de la base de datos pueden no ser correctamente interpretadas por .NET. Así, para el campo "Date Val Def" se obtiene "sysdate" (sin las comillas dobles). Al igual que ocurre en SQL Server, durante la fase de comprobación de la configuración se producirá un error y se indican los formatos admitidos por la aplicación para las fechas (que suelen ser dependientes de la configuración del sistema). En los ficheros de _Error.log aparecerán mensajes similares a los siguientes:

    .NET Connections (Managed Driver (Bulk Copy) (CheckBox "Usar Arrays" no marcada))
            Hoja 'Oracle - Val Def-Val Null': Comprobando ...
    
    Celda: , Valor: sysdate, Tabla: Tabla Valores Defecto, Columna: Date Val Def
        El contenido de la Celda no ha podido convertirse al tipo de datos DATE
    
    Para las fechas con formato de texto se admiten estos formatos:
    dd/MM/yyyy
    dd/MM/yy
    d/MM/yy
    .....
    MMMM dd
    hh:mm tt
    h:mm tt
    yyyy MMMM
    
    
    Se ha producido una excepción durante la comprobación de si la Hoja Excel 'Oracle - Val Def-Val Null' ha sufrido modificaciones que afectan a la carga de datos.
    {
      "$id": "1",
      "$type": "System.ArithmeticException, mscorlib",
      "Message": "Celda: , Valor: sysdate, Tabla: Tabla Valores Defecto, Columna: Date Val Def
        El contenido de la celda no ha podido convertirse en una fecha.
        El Managed Driver de Oracle con NO Arrays contiene un bug que permite insertar datos que no cumplen las restricciones de la columna.
        Marque la opción \"Sin Errores de Conversión\" para cargar el valor por defecto.
        No se ejecutará la Fase de carga de datos.
    ",
      "Data": {
        "$type": "System.Collections.ListDictionaryInternal, mscorlib"
      },
      "InnerException": null,
      "HelpLink": null,
      "Source": "ExcelToDatabaseWpf",
      "HResult": -2147024362
    }
    
            Hoja 'Oracle - Val Def-Val Null': Comprobación Finalizada. Con modificaciones o fallos.
    
    .NET Connections (Managed Driver (Array Binding) (CheckBox "Usar Arrays" marcado))
    
            Hoja 'Oracle - Val Def-Val Null': Comprobando ...
    
    Celda: , Valor: sysdate, Tabla: Tabla Valores Defecto, Columna: Date Val Def
        El contenido de la Celda no ha podido convertirse al tipo de datos DATE
    
    Para las fechas con formato de texto se admiten estos formatos:
    dd/MM/yyyy
    dd/MM/yy
    d/MM/yy
    .....
    MMMM dd
    hh:mm tt
    h:mm tt
    yyyy MMMM
    
    El valor por defecto 'sysdate' indicado para la Columna 'Date Val Def'
    no puede ser convertido al tipo de datos de la columna.
    
    {
      "$id": "1",
      "$type": "System.ArgumentException, mscorlib",
      "Message": "DefaultValue de la columna Date Val Def es de tipo System.String, pero la columna es de tipo Oracle.ManagedDataAccess.Types.OracleDate.",
      "ParamName": null,
      "Data": {
        "$type": "System.Collections.ListDictionaryInternal, mscorlib"
      },
      "InnerException": {
        "$type": "System.InvalidCastException, mscorlib",
        "Message": "Conversión no válida desde 'System.String' hasta 'Oracle.ManagedDataAccess.Types.OracleDate'.",
        "Data": {
          "$type": "System.Collections.ListDictionaryInternal, mscorlib"
        },
        "InnerException": null,
        "HelpLink": null,
        "Source": "mscorlib",
        "HResult": -2147467262
      },
      "HelpLink": null,
      "Source": "System.Data",
      "HResult": -2147024809
    }
    
            Hoja 'Oracle - Val Def-Val Null': Comprobación Finalizada. Con modificaciones o fallos.
    
    Conexiones OLE DB (Oracle® Provider for OLE DB) y ODBC (Oracle ODBC Driver)
    
            Hoja 'Oracle - Val Def-Val Null': Comprobando ...
    
    Celda: , Valor: sysdate, Tabla: Tabla Valores Defecto, Columna: Date Val Def
        El contenido de la Celda no ha podido convertirse al tipo de datos DATE
    
    Para las fechas con formato de texto se admiten estos formatos:
    dd/MM/yyyy
    dd/MM/yy
    d/MM/yy
    .....
    MMMM dd
    hh:mm tt
    h:mm tt
    yyyy MMMM
    

    En este caso se propone como valor por defecto la palabra clave "Ahora" o "Now", la cual hace que se inserte la fecha y hora en que da comienzo la carga de datos, de forma que todos los registros insertados en la tabla que utilicen este valor por defecto tendrán el mismo dato. Se ha tomado esta decisión y no la de insertar la fecha y hora en que se inserta cada registro (que realmente es lo que hace la base de datos) por que se desea que queden marcados dichos registros como que se insertaron conjuntamente.

    Se recomienda encarecidamente ajustar correctamente estos valores por defecto para que se ajusten al comportamiento deseado.

Preguntas Frecuentes

¿Cómo maneja Excel To Database las celdas vacías?

Las interpreta como NULL por defecto, pero permite definir un valor de sustitución personalizado que el software inyectará antes de enviar el dato al driver de la base de datos.

¿Por qué es obligatorio el valor por defecto en campos NOT NULL?

Para garantizar la robustez del proceso. Al detectarlo en la fase de comprobación, el software evita que la base de datos rechace la carga masiva, ahorrando tiempo y problemas de integridad.

¿Cómo afecta esto al rendimiento de la carga masiva?

El procesamiento se realiza en memoria durante la fase de mapeo, lo que añade una latencia imperceptible pero garantiza que el driver reciba datos ya validados, evitando costosos rollbacks o errores de inserción a mitad de proceso.