BULK INSERT (Transact-SQL)

Se aplica a: SQL Server Azure SQL Database Azure SQL Managed Instance

Importa un archivo de datos en una tabla o vista de base de datos con un formato especificado por el usuario en SQL Server

Convenciones de sintaxis de Transact-SQL

Sintaxis

BULK INSERT
   { database_name.schema_name.table_or_view_name | schema_name.table_or_view_name | table_or_view_name }
      FROM 'data_file'
     [ WITH
    (
   [ [ , ] DATA_SOURCE = 'data_source_name' ]

   -- text formatting options
   [ [ , ] CODEPAGE = { 'RAW' | 'code_page' | 'ACP' | 'OEM' } ]
   [ [ , ] DATAFILETYPE = { 'char' | 'native' | 'widechar' | 'widenative' } ]
   [ [ , ] ROWTERMINATOR = 'row_terminator' ]
   [ [ , ] FIELDTERMINATOR = 'field_terminator' ]
   [ [ , ] FORMAT = 'CSV' ]
   [ [ , ] FIELDQUOTE = 'quote_characters']

   [ [ , ] FIRSTROW = first_row ]
   [ [ , ] LASTROW = last_row ]

   -- input file format options
   [ [ , ] FORMATFILE = 'format_file_path' ]
   [ [ , ] FORMATFILE_DATA_SOURCE = 'data_source_name' ]

   -- error handling options
   [ [ , ] MAXERRORS = max_errors ]
   [ [ , ] ERRORFILE = 'file_name' ]
   [ [ , ] ERRORFILE_DATA_SOURCE = 'errorfile_data_source_name' ]

   -- database options
   [ [ , ] KEEPIDENTITY ]
   [ [ , ] KEEPNULLS ]
   [ [ , ] FIRE_TRIGGERS ]
   [ [ , ] CHECK_CONSTRAINTS ]
   [ [ , ] TABLOCK ]

   -- source options
   [ [ , ] ORDER ( { column [ ASC | DESC ] } [ ,...n ] ) ]
   [ [ , ] ROWS_PER_BATCH = rows_per_batch ]
   [ [ , ] KILOBYTES_PER_BATCH = kilobytes_per_batch 
   [ [ , ] BATCHSIZE = batch_size ]

    )]

Argumentos

database_name

Nombre de la base de datos donde reside la tabla o la vista especificada. Si no se especifica, database_name es la base de datos actual.

schema_name

Especifica el nombre del esquema de la tabla o vista. schema_name es opcional si el esquema predeterminado para el usuario que realiza la operación de importación masiva es el esquema de la tabla o vista especificada. Si no se especifica schema y el esquema predeterminado del usuario que realiza la operación de importación masiva es diferente de la tabla o la vista especificada, SQL Server devuelve un mensaje de error y se cancela la operación de importación masiva.

table_name

Especifica el nombre de la tabla o vista en la que se va a realizar una importación masiva de datos. Solo se pueden utilizar vistas en las que todas las columnas hagan referencia a la misma tabla base. Para obtener más información sobre las restricciones para cargar datos en vistas, vea INSERT (Transact-SQL).

FROM 'data_file'

Especifica la ruta de acceso completa al archivo de datos que contiene los datos que se van a importar a la tabla o vista especificada. BULK INSERT puede importar datos desde un disco o Azure Blob Storage (incluidos una ubicación de red, disquete, disco duro, etc.).

data_file debe especificar una ruta de acceso válida del servidor en el que se ejecuta SQL Server. Si data_file es un archivo remoto, especifique un nombre UNC (convención de nomenclatura universal). Un nombre UNC tiene el formato \\SystemName\ShareName\Path\FileName. Por ejemplo:

BULK INSERT Sales.Orders
FROM '\\SystemX\DiskZ\Sales\data\orders.dat';

A partir de SQL Server 2017 (14.x), data_file puede estar en Azure Blob Storage. En ese caso, deberá especificar la opción data_source_name. Para obtener un ejemplo, vea Importación de datos desde un archivo en Azure Blob Storage.

Azure SQL Database solo admite la lectura desde Azure Blob Storage.

BATCHSIZE = batch_size

Especifica el número de filas de un lote. Cada lote se copia en el servidor como una transacción. Si no ocurre así, SQL Server confirma o revierte la transacción de cada lote. De forma predeterminada, todos los datos del archivo de datos especificado componen un lote. Para obtener información sobre las consideraciones de rendimiento, vea Consideraciones de rendimiento más adelante en este artículo.

CHECK_CONSTRAINTS

Especifica que deben comprobarse todas las restricciones de la tabla o vista de destino durante la operación de importación masiva. Sin la opción CHECK_CONSTRAINTS, se omiten las restricciones CHECK y FOREIGN KEY, y, después de la operación, la restricción sobre la tabla se marca como de no confianza.

Las restricciones UNIQUE y PRIMARY KEY se exigen siempre. Cuando se importa a una columna de caracteres definida con la restricción NOT NULL, BULK INSERT inserta una cadena vacía cuando no hay valor en el archivo de texto.

En algún momento, debe examinar las restricciones de toda la tabla. Si la tabla no estaba vacía antes de la operación de importación masiva, el costo de revalidar la restricción puede superar del costo de aplicar restricciones CHECK a los datos incrementales.

Una situación en la que quizá desee que las restricciones estén deshabilitadas (comportamiento predeterminado) es si los datos de entrada contienen filas que infringen las restricciones. Con las restricciones CHECK deshabilitadas, puede importar los datos y utilizar después instrucciones Transact-SQL para quitar los datos no válidos.

Nota

La opción MAXERRORS no se aplica a la comprobación de restricciones.

CODEPAGE = { 'ACP' | 'OEM' | 'RAW' | 'code_page' }

Especifica la página de códigos de los datos incluidos en el archivo de datos. CODEPAGE solo es pertinente si los datos contienen columnas de tipo char, varchar o text con valores de caracteres mayores que 127 o menores que 32. Para obtener un ejemplo, vea Especificación de una página de códigos.

CODEPAGE no es una opción admitida en SQL Server 2017 (14.x). Para SQL Server 2019 (15.x), solo la opción "RAW" se permite para CODEPAGE.

Debe especificar un nombre de intercalación para cada columna de un archivo de formato.

Valor de CODEPAGE Descripción
ACP Convierte columnas de los tipos de datos char, varchar o text de la página de códigos ANSI/Microsoft Windows (ISO 1252) a la página de códigos de SQL Server.
OEM (valor predeterminado) Convierte columnas de los tipos de datos char, varchar o text de la página de códigos OEM a la página de códigos de SQL Server.
RAW No se realiza ninguna conversión entre páginas de códigos. RAW es la opción más rápida.
code_page Número específico de una página de códigos; por ejemplo, 850.

Las versiones anteriores a SQL Server 2016 (13.x) no admiten la página de códigos 65001 (codificación UTF-8).

DATAFILETYPE = { 'char' | 'native' | 'widechar' | 'widenative' }

Especifica que BULK INSERT realiza la operación de importación con el valor de tipo de archivo de datos especificado.

Valor de DATAFILETYPE Todos los datos representados en:
char (valor predeterminado) Formato de caracteres.

Para obtener más información, vea Usar el formato de caracteres para importar o exportar datos (SQL Server).
native Tipos de datos nativos (base de datos). Cree el archivo de datos nativos mediante la importación masiva de datos desde SQL Server con la utilidad bcp.

El valor native ofrece una alternativa de mayor rendimiento al valor char. Se recomienda usar el formato nativo cuando se realiza una transferencia de datos en bloque entre varias instancias de SQL Server mediante un archivo de datos que no contiene juegos de caracteres extendidos o de doble byte (DBCS).

Para obtener más información, vea Usar el formato nativo para importar o exportar datos (SQL Server).
widechar Caracteres Unicode.

Para obtener más información, vea Usar el formato de caracteres Unicode para importar o exportar datos (SQL Server).
widenative Tipos de datos nativos (base de datos), salvo en las columnas char, varchar y text, en las que los datos se almacenan como datos Unicode. Cree el archivo de datos widenative mediante la importación masiva de datos desde SQL Server con la utilidad bcp.

El valor widenative ofrece una alternativa de mayor rendimiento a widechar. Si el archivo de datos contiene caracteres extendidos ANSI, especifique widenative.

Para obtener más información, vea Usar el formato nativo Unicode para importar o exportar datos (SQL Server).

DATA_SOURCE = 'data_source_name'

Se aplica a: SQL Server 2017 (14.x) y Azure SQL Database.

Especifica un origen de datos externo con nombre que apunta a la ubicación de Azure Blob Storage del archivo que se importará. El origen de datos externo se debe crear con la opción TYPE = BLOB_STORAGE que se ha incluido en SQL Server 2017 (14.x). Para más información, vea CREATE EXTERNAL DATA SOURCE. Para obtener un ejemplo, vea Importación de datos desde un archivo en Azure Blob Storage.

ERRORFILE = 'error_file_path'

Especifica el archivo utilizado para recopilar filas que tienen errores de formato y no pueden convertirse en un conjunto de filas OLE DB. Estas filas se copian en este archivo de errores desde el archivo de datos "tal cual".

El archivo de errores se crea cuando se ejecuta el comando. Se produce un error si el archivo ya existe. Además, se crea un archivo de control con la extensión .ERROR.txt que hace referencia a cada fila del archivo de error y proporciona diagnósticos de errores. Tan pronto como se corrigen los errores, se pueden cargar los datos.

A partir de SQL Server 2017 (14.x), error_file_path puede estar en Azure Blob Storage.

ERRORFILE_DATA_SOURCE = 'errorfile_data_source_name'

Se aplica a: SQL Server 2017 (14.x).

Especifica un origen de datos externo con nombre que apunta a la ubicación de Azure Blob Storage del archivo de error que contendrá los errores encontrados durante la importación. El origen de datos externo se debe crear con la opción TYPE = BLOB_STORAGE que se ha incluido en SQL Server 2017 (14.x). Para más información, vea CREATE EXTERNAL DATA SOURCE.

FIRSTROW = first_row

Especifica el número de la primera fila que se va a cargar. El valor predeterminado es la primera fila del archivo de datos especificado. FIRSTROW está en base 1.

El atributo FIRSTROW no está pensado para omitir encabezados de columna. La instrucción BULK INSERT no permite omitir encabezados. Si decide omitir filas, el Motor de base de datos de SQL Server solo analiza los terminadores de campo y no valida los datos en los campos de las filas omitidas.

FIRE_TRIGGERS

Especifica que se ejecutarán todos los desencadenadores de inserción definidos en la tabla de destino durante la operación de importación masiva. Si se definen desencadenadores para operaciones INSERT en la tabla de destino, se activan para cada lote completado.

Si no se especifica FIRE_TRIGGERS, no se ejecutará ningún desencadenador de inserción.

FORMATFILE_DATA_SOURCE = 'data_source_name'

Se aplica a: SQL Server 2017 (14.x).

Especifica un origen de datos externo con nombre que apunta a la ubicación de Azure Blob Storage del archivo de formato que definirá el esquema de los datos importados. El origen de datos externo se debe crear con la opción TYPE = BLOB_STORAGE que se ha incluido en SQL Server 2017 (14.x). Para más información, vea CREATE EXTERNAL DATA SOURCE.

KEEPIDENTITY

Especifica que se usará el valor o valores de identidad del archivo de datos importado para la columna de identidad. Si no se especifica KEEPIDENTITY, los valores de identidad de esta columna se comprueban pero no se importan y SQL Server asigna automáticamente valores únicos basados en los valores de inicialización y de incremento especificados durante la creación de la tabla. Si el archivo de datos no contiene valores para la columna de identidad de la tabla o vista, utilice un archivo de formato para especificar que se debe omitir la columna de identidad de la tabla o vista cuando se importen los datos; SQL Server asigna automáticamente valores únicos para la columna. Para obtener más información, vea DBCC CHECKIDENT (Transact-SQL).

Si quiere obtener más información sobre cómo mantener valores de identidad, vea Mantener valores de identidad al importar datos de forma masiva (SQL Server).

KEEPNULLS

Especifica que las columnas vacías deben conservar un valor NULL durante la operación de importación masiva, en lugar de tener valores predeterminados para las columnas insertadas. Para obtener más información, vea Mantener valores NULL o usar valores predeterminados durante la importación en bloque (SQL Server).

KILOBYTES_PER_BATCH = kilobytes_per_batch

Especifica el número aproximado de kilobytes (KB) de datos por lote como kilobytes_per_batch. De forma predeterminada, el valor de KILOBYTES_PER_BATCH es desconocido. Para obtener información sobre las consideraciones de rendimiento, vea Consideraciones de rendimiento más adelante en este artículo.

LASTROW = last_row

Especifica el número de la última fila que va a cargarse. El valor predeterminado es 0, que indica la última fila del archivo de datos especificado.

MAXERRORS = max_errors

Especifica el número máximo de errores de sintaxis permitidos en los datos antes de cancelar la operación de importación masiva. Cada fila que no se puede importar con la operación de importación masiva se omite y se considera un error. Si no se especifica max_errors, el valor predeterminado es 10.

La opción MAX_ERRORS no se aplica a comprobaciones de restricciones ni para convertir tipos de datos money y bigint.

ORDER ( { column [ ASC | DESC ] } [ ,... n ] )

Especifica la forma en que están ordenados los datos del archivo de datos. El rendimiento de la importación masiva mejora si los datos importados se ordenan según el índice clúster de la tabla, si lo hay. Si el archivo de datos se ordena siguiendo otro criterio que no sea el orden de una clave de índice agrupado, o si no hay ningún índice agrupado en la tabla, se omite la cláusula ORDER. Los nombres de columna facilitados deben ser nombres válidos en la tabla de destino. De forma predeterminada, la operación de inserción masiva presupone que los datos del archivo no están ordenados. En las importaciones masivas optimizadas, SQL Server también valida que los datos importados estén ordenados.

n es un marcador de posición que indica que se pueden especificar varias columnas.

ROWS_PER_BATCH = rows_per_batch

Indica el número aproximado de filas de datos del archivo de datos.

De forma predeterminada, todos los datos del archivo de datos se envían al servidor en una sola transacción y el optimizador de consultas desconoce el número de filas del lote. Si especifica ROWS_PER_BATCH (con el valor > 0), el servidor utiliza este valor para optimizar la operación de importación masiva. El valor especificado para ROWS_PER_BATCH debe ser aproximadamente el mismo que el número real de filas. Para obtener información sobre las consideraciones de rendimiento, vea Consideraciones de rendimiento más adelante en este artículo.

TABLOCK

Especifica que se obtiene un bloqueo de tabla durante la operación de importación masiva. Varios clientes pueden cargar una tabla simultáneamente si ésta no tiene índices y se especifica TABLOCK. De forma predeterminada, el comportamiento del bloqueo viene determinado por la opción de tabla table lock on bulk load. Al mantener un bloqueo durante la operación de importación masiva, se reduce la contención por bloqueos de la tabla y en algunos casos puede mejorarse notablemente el rendimiento. Para obtener información sobre las consideraciones de rendimiento, vea Consideraciones de rendimiento más adelante en este artículo.

En un índice de almacén de columnas, el comportamiento de bloqueo es diferente porque se divide internamente en varios conjuntos de filas. Cada subproceso carga datos exclusivamente en cada conjunto de filas aplicando un bloqueo X en el conjunto de filas, lo que permite cargar datos en paralelo con las sesiones de carga de datos que se están realizando al mismo tiempo. El uso de la opción TABLOCK hará que el subproceso realice un bloqueo X en la tabla (a diferencia del bloqueo de actualización masiva para conjuntos de filas tradicionales) que impedirá que otros subprocesos simultáneos carguen datos al mismo tiempo.

Opciones de formato de archivos de entrada

FORMAT = 'CSV'

Se aplica a: SQL Server 2017 (14.x).

Especifica un archivo de valores separados por comas conforme a la norma RFC 4180.

BULK INSERT Sales.Orders
FROM '\\SystemX\DiskZ\Sales\data\orders.csv'
WITH ( FORMAT = 'CSV');

FIELDQUOTE = 'field_quote'

Se aplica a: SQL Server 2017 (14.x).

Especifica un carácter que se usará como carácter de comillas en el archivo CSV. Si no se especifica, se usará el carácter de comillas (") como carácter de comillas, según define la norma RFC 4180.

FORMATFILE = 'format_file_path'

Especifica la ruta de acceso completa de un archivo de formato. Un archivo de formato describe el archivo de datos que contiene respuestas almacenadas creado con la utilidad bcp en la misma tabla o vista. Se debe usar el archivo de formato si:

  • El archivo de datos contiene un número de columnas mayor o menor que la tabla o vista.
  • Las columnas están en un orden diferente.
  • Los delimitadores de columna varían.
  • Hay otros cambios en el formato de los datos. Los archivos de formato se suelen crear con la utilidad bcp y se modifican con un procesador de texto si es necesario. Para más información, vea Utilidad bcp y Creación de un archivo de formato.

A partir de SQL Server 2017 (14.x), y también en Azure SQL Database, format_file_path puede estar en Azure Blob Storage.

FIELDTERMINATOR = 'field_terminator'

Especifica el terminador de campo que se va a usar para archivos de datos de tipo char y widechar. El terminador de campo predeterminado es \t (tabulador). Para obtener más información, vea Especificar terminadores de campo y de fila (SQL Server).

ROWTERMINATOR = 'row_terminator'

Especifica el terminador de fila que se va a usar para archivos de datos de tipo char y widechar. El terminador de fila predeterminado es \r\n (carácter de nueva línea). Para obtener más información, vea Especificar terminadores de campo y de fila (SQL Server).

Compatibilidad

BULK INSERT aplica una estricta validación y comprobación de los datos leídos de un archivo que pueden dar lugar a errores en los scripts existentes cuando se ejecutan en datos no válidos. Por ejemplo, BULK INSERT comprueba que:

  • Las representaciones nativas de los tipos de datos float o real son válidas.
  • Los datos Unicode tienen una longitud de bytes uniforme.

Tipos de datos

Conversiones de tipos de datos de cadena a decimal

Las conversiones de tipos de datos de cadena a decimal usadas en BULK INSERT siguen las mismas reglas que la función CONVERT de Transact-SQL, que rechaza las cadenas que representan valores numéricos con notación científica. Por lo tanto, BULK INSERT trata esas cadenas como valores no válidos y genera errores de conversión.

Para solucionar este comportamiento, use un archivo de formato para la importación masiva de datos de tipo float con notación científica en una columna con valores decimales. En el archivo de formato, describa explícitamente la columna como de datos real o float. Para obtener más información sobre estos tipos de datos, vea float y real (Transact-SQL).

Los archivos de formato representan datos real como el tipo de datos SQLFLT4 y datos float como el tipo de datos SQLFLT8. Para obtener más información sobre archivos de formato distintos de XML, vea Especificar el tipo de almacenamiento de archivos mediante bcp (SQL Server).

Ejemplo de importación de un valor numérico que utiliza notación científica

En este ejemplo se utiliza la siguiente tabla en la base de datos bulktest:

CREATE TABLE dbo.t_float(c1 FLOAT, c2 DECIMAL (5,4));

El usuario desea importar masivamente datos en la tabla t_float. El archivo de datos (C:\t_float-c.dat) contiene datos float con notación científica; por ejemplo:

8.0000000000000002E-2 8.0000000000000002E-2

Al copiar este ejemplo, tenga en cuenta los diferentes editores de texto y codificaciones que guardan los caracteres de tabulación (\t) como espacios. Se espera un carácter de tabulación más adelante en este ejemplo.

No obstante, BULK INSERT no puede importar estos datos directamente a t_float, ya que su segunda columna, c2, utiliza el tipo de datos decimal. Por lo tanto, es necesario un archivo de formato. El archivo de formato debe asignar los datos float con notación científica al formato decimal de la columna c2.

El siguiente archivo de formato utiliza el tipo de datos SQLFLT8 para asignar el segundo campo de datos a la segunda columna:

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="30"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="30"/> </RECORD> <ROW>
<COLUMN SOURCE="1" NAME="c1" xsi:type="SQLFLT8"/>
<COLUMN SOURCE="2" NAME="c2" xsi:type="SQLFLT8"/> </ROW> </BCPFORMAT>

Para utilizar este archivo de formato (con el nombre de archivo C:\t_floatformat-c-xml.xml) para importar los datos de prueba en la tabla de prueba, emita la siguiente instrucción de Transact-SQL:

BULK INSERT bulktest.dbo.t_float
FROM 'C:\t_float-c.dat' WITH (FORMATFILE = 'C:\t_floatformat-c-xml.xml');

Importante

Azure SQL Database solo admite la lectura desde Azure Blob Storage.

Tipos de datos para importar o exportar masivamente documentos SQLXML

Para importar o exportar de forma masiva datos SQLXML, utilice uno de los tipos de datos siguientes en el archivo de formato:

Tipo de datos Efecto
SQLCHAR o SQLVARCHAR Los datos se envían a la página de códigos del cliente o a la página de códigos implícita por la intercalación. El efecto es el mismo que si se especifica DATAFILETYPE = 'char' sin especificar un archivo de formato.
SQLNCHAR o SQLNVARCHAR Los datos se envían como datos Unicode. El efecto es el mismo que si se especifica DATAFILETYPE = 'widechar' sin especificar un archivo de formato.
SQLBINARY o SQLVARBIN Los datos se envían sin realizar ninguna conversión.

Comentarios

Para obtener una comparación de la instrucción BULK INSERT, la instrucción INSERT ... SELECT * FROM OPENROWSET(BULK...) y el comando bcp, vea Importar y exportar datos de forma masiva (SQL Server).

Para obtener más información sobre cómo preparar datos para importaciones masivas, vea Preparar los datos para exportar o importar de forma masiva (SQL Server).

La instrucción BULK INSERT se puede ejecutar en una transacción definida por el usuario para importar datos en una tabla o una vista. Opcionalmente, para utilizar varias coincidencias para la importación masiva de datos, una transacción puede especificar la cláusula BATCHSIZE en la instrucción BULK INSERT. Si una transacción de varios lotes se revierte, cada lote que la transacción ha enviado a SQL Server se revierte.

Interoperabilidad

Importa datos desde un archivo CSV

A partir de SQL Server 2017 (14.x), BULK INSERT admite el formato CSV, al igual que Azure SQL Database.

Antes de SQL Server 2017 (14.x), las operaciones de importación masiva SQL Server no admiten archivos de valores separados por comas (CSV). Sin embargo, en algunos casos se puede utilizar un archivo de valores separados por comas (CSV) como archivo de datos para una importación masiva de datos en SQL Server. Para obtener información sobre los requisitos para importar datos desde un archivo de datos CSV, vea Preparar los datos para exportar o importar de forma masiva (SQL Server).

Comportamiento del registro

Para más información sobre cuándo se incluyen en el registro de transacciones las operaciones de inserción de filas realizadas durante una importación en bloque a SQL Server, consulte Requisitos previos para el registro mínimo durante la importación en bloque. En Azure SQL Database no se admite el registro mínimo.

Restricciones

Cuando se usa un archivo de formato con BULK INSERT, solo se puede especificar un máximo de 1024 campos. Es el mismo número máximo de columnas permitido en una tabla. Si usa un archivo de formato con BULK INSERT con un archivo de datos que contenga más de 1024 campos, BULK INSERT genera el error 4822. La utilidad bcp no tiene esta limitación, por lo que para los archivos de datos que contengan más de 1024 campos, use BULK INSERT sin un archivo de formato, o bien use el comando bcp.

Consideraciones de rendimiento

Si el número de páginas que van a vaciarse en un único lote supera un umbral interno, podría producirse un examen completo del grupo de búferes para identificar qué páginas se han de vaciar cuando el lote se confirme. Este examen completo puede afectar de forma desfavorable al rendimiento de la importación masiva. Un caso en el que es probable que se supere el umbral interno se produce cuando un grupo de búferes grande se combina con un subsistema de E/S lento. Para evitar los desbordamientos del búfer en equipos grandes, no utilice la sugerencia TABLOCK (que quita la optimización masiva) o use un tamaño de lote menor (que la preserva).

Debe probar con varios tamaños de lote con la carga de datos para averiguar lo que funciona mejor en su caso. Recuerde que el tamaño de lote tiene implicaciones de reversión parcial. Si se produce un error en el proceso, antes de volver a usar BULK INSERT es posible que tenga que realizar un trabajo manual adicional para quitar una parte de las filas que se insertaron correctamente, antes de que se produjera un error.

Con Azure SQL Database, considere la posibilidad de aumentar temporalmente el nivel de rendimiento de la base de datos o la instancia antes de la importación si va a importar un gran volumen de datos.

Seguridad

Delegación de cuentas de seguridad (suplantación)

Si un usuario utiliza un inicio de sesión de SQL Server , se utilizará el perfil de seguridad de la cuenta de proceso de SQL Server . Un inicio de sesión que use autenticación de SQL Server no se puede autenticar fuera del Motor de base de datos. Por tanto, cuando un inicio de sesión que usa autenticación de SQL Server inicia un comando BULK INSERT, la conexión con los datos se realiza usando el contexto de seguridad de la cuenta de proceso de SQL Server (la cuenta usada por el servicio Motor de base de datos de SQL Server).

Para leer correctamente los datos de origen, debe conceder acceso a los datos de origen a la cuenta usada por el Motor de base de datos de SQL Server. Por el contrario, si un usuario de SQL Server ha iniciado sesión mediante autenticación de Windows, el usuario solo puede leer los archivos a los que la cuenta de usuario tiene acceso, independientemente del perfil de seguridad del proceso de SQL Server .

Es posible que reciba un error 4861 si ejecuta la instrucción BULK INSERT usando sqlcmd o osql desde un equipo, insertando datos en SQL Server en otro equipo y especificando data_file en un tercer equipo mediante una ruta de acceso UNC.

Para resolver este error, use la autenticación de SQL Server y especifique un inicio de sesión de SQL Server que use el perfil de seguridad de la cuenta del proceso de SQL Server, o bien configure Windows para habilitar la delegación de la cuenta de seguridad. Para obtener información acerca de cómo habilitar una cuenta de usuario para que sea de confianza para la delegación, vea la Ayuda de Windows.

Para obtener más información sobre esta y otras consideraciones de seguridad, vea Importación en bloque de datos mediante las instrucciones BULK INSERT u OPENROWSET(BULK...) (SQL Server).

Cuando se importe desde Azure Blob Storage y los datos no sean públicos (acceso anónimo), cree una instancia de DATABASE SCOPED CREDENTIAL basada en una clave SAS cifrada con MASTER KEY y, después, cree un origen de base de datos externo para usarlo en el comando BULK INSERT.

Como alternativa, cree una CREDENCIAL CON ÁMBITO DE BASE DE DATOS basada en MANAGED IDENTITY para autorizar solicitudes de acceso a datos en cuentas de almacenamiento no públicas. Cuando se usa MANAGED IDENTITY, Azure Storage debe conceder permisos a la identidad administrada de la instancia mediante la adición del rol integrado de control de acceso basado en roles (RBAC) Colaborador de datos de blobs de almacenamiento. Este rol proporciona acceso de lectura y escritura a la identidad administrada de los contenedores de Azure Blob Storage necesarios. Azure SQL Managed Instance dispone de una identidad administrada asignada por el sistema, y también puede tener una o varias identidades administradas asignadas por el usuario. Puede usar identidades administradas asignadas por el sistema o identidades administradas asignadas por el usuario para autorizar las solicitudes. Para la autorización, se utilizaría la identidad default de la instancia administrada (es decir, la identidad administrada asignada por el usuario principal o la identidad administrada asignada por el sistema, si no se especifica la identidad administrada asignada por el usuario). Para obtener un ejemplo, vea Importación de datos desde un archivo en Azure Blob Storage.

Importante

La identidad administrada solo se aplica a Azure SQL. SQL Server no admite identidades administradas.

Permisos

Se requieren los permisos INSERT y ADMINISTER BULK OPERATIONS. En Azure SQL Database, se necesitan los permisos INSERT y ADMINISTER DATABASE BULK OPERATIONS. No se admiten los permisos ADMINISTER BULK OPERATIONS o el rol bulkadmin para SQL Server en Linux. Solo sysadmin puede realizar inserciones masivas para SQL Server en Linux.

Además, es necesario el permiso ALTER TABLE si se da una o varias de las siguientes circunstancias:

  • Existen restricciones y no se ha especificado la opción CHECK_CONSTRAINTS.

    La deshabilitación de restricciones es el comportamiento predeterminado. Para comprobar las restricciones CHECK explícitamente, utilice la opción CHECK_CONSTRAINTS.

  • Existen desencadenadores y no se ha especificado la opción FIRE_TRIGGER.

    De forma predeterminada, los desencadenadores no se activan. Para activar los desencadenadores explícitamente, use la opción FIRE_TRIGGER.

  • Se utiliza la opción KEEPIDENTITY para importar el valor de identidad de un archivo de datos.

Ejemplos

A. Use canalizaciones para importar datos de un archivo

En el siguiente ejemplo se importa información detallada de pedidos en la tabla AdventureWorks2022.Sales.SalesOrderDetail desde un archivo de datos especificado utilizando una canalización (|) como el terminador de campo y |\n como el terminador de fila.

BULK INSERT AdventureWorks2022.Sales.SalesOrderDetail
   FROM 'f:\orders\lineitem.tbl'
   WITH
      (
         FIELDTERMINATOR = ' |'
         , ROWTERMINATOR = ' |\n'
      );

Importante

Azure SQL Database solo admite la lectura desde Azure Blob Storage.

B. Use el argumento FIRE_TRIGGERS

En el ejemplo siguiente se especifica el argumento FIRE_TRIGGERS.

BULK INSERT AdventureWorks2022.Sales.SalesOrderDetail
   FROM 'f:\orders\lineitem.tbl'
   WITH
     (
         FIELDTERMINATOR = ' |'
         , ROWTERMINATOR = ':\n'
         , FIRE_TRIGGERS
      );

Importante

Azure SQL Database solo admite la lectura desde Azure Blob Storage.

C. Use el salto de línea como terminador de fila

En el siguiente ejemplo se importa un archivo que utiliza el salto de línea como terminador de fila, igual que en una salida de UNIX:

DECLARE @bulk_cmd VARCHAR(1000);
SET @bulk_cmd = 'BULK INSERT AdventureWorks2022.Sales.SalesOrderDetail
FROM ''<drive>:\<path>\<filename>''
WITH (ROWTERMINATOR = '''+CHAR(10)+''')';
EXEC(@bulk_cmd);

Nota

Debido a la forma en que Microsoft Windows trata los archivos de texto, \n se reemplaza automáticamente por \r\n.

Importante

Azure SQL Database solo admite la lectura desde Azure Blob Storage.

D. Especificar una página de código

En este ejemplo se muestra cómo especificar una página de código.

BULK INSERT MyTable
FROM 'D:\data.csv'
WITH
( CODEPAGE = '65001'
   , DATAFILETYPE = 'char'
   , FIELDTERMINATOR = ','
);

Importante

Azure SQL Database solo admite la lectura desde Azure Blob Storage.

E. Importa datos desde un archivo CSV

En el ejemplo siguiente se muestra cómo especificar un archivo CSV, omitir el encabezado (primera fila), utilizar ; como terminador de campo y 0x0a como terminador de línea:

BULK INSERT Sales.Invoices
FROM '\\share\invoices\inv-2016-07-25.csv'
WITH (FORMAT = 'CSV'
      , FIRSTROW = 2
      , FIELDQUOTE = '\'
      , FIELDTERMINATOR = ';'
      , ROWTERMINATOR = '0x0a');

El siguiente ejemplo muestra cómo especificar un archivo CSV en formato UTF-8 (utilizando un CODEPAGE de 65001), omitiendo el encabezado (primera fila), utilizando ; como terminador de campo y 0x0a como terminador de línea:

BULK INSERT Sales.Invoices
FROM '\\share\invoices\inv-2016-07-25.csv'
WITH ( CODEPAGE = '65001'
      , FORMAT = 'CSV'
      , FIRSTROW = 2
      , FIELDQUOTE = '\'
      , FIELDTERMINATOR = ';'
      , ROWTERMINATOR = '0x0a');

Importante

Azure SQL Database solo admite la lectura desde Azure Blob Storage.

F. Importar datos desde un archivo en Azure Blog Storage

En el ejemplo siguiente se muestra cómo cargar datos desde un archivo CSV en una ubicación de Azure Blob Storage en la que se ha creado una Firma de acceso compartido (SAS). La ubicación de Azure Blob Storage se configura como un origen de datos externo, que requiere una credencial de ámbito de base de datos que use una clave SAS cifrada mediante una clave maestra en la base de datos de usuario.

--> Optional - a MASTER KEY is not required if a DATABASE SCOPED CREDENTIAL is not required because the blob is configured for public (anonymous) access!
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'YourStrongPassword1';
GO
--> Optional - a DATABASE SCOPED CREDENTIAL is not required because the blob is configured for public (anonymous) access!
CREATE DATABASE SCOPED CREDENTIAL MyAzureBlobStorageCredential
WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
SECRET = '******srt=sco&sp=rwac&se=2017-02-01T00:55:34Z&st=2016-12-29T16:55:34Z***************';

-- NOTE: Make sure that you don't have a leading ? in SAS token, and
-- that you have at least read permission on the object that should be loaded srt=o&sp=r, and
-- that expiration period is valid (all dates are in UTC time)

CREATE EXTERNAL DATA SOURCE MyAzureBlobStorage
WITH ( TYPE = BLOB_STORAGE,
          LOCATION = 'https://****************.blob.core.windows.net/invoices'
          , CREDENTIAL = MyAzureBlobStorageCredential --> CREDENTIAL is not required if a blob is configured for public (anonymous) access!
);

BULK INSERT Sales.Invoices
FROM 'inv-2017-12-08.csv'
WITH (DATA_SOURCE = 'MyAzureBlobStorage');

En el ejemplo siguiente se muestra cómo usar el comando BULK INSERT para cargar datos desde un archivo CSV en una ubicación de Azure Blob Storage que usa identidades administradas. La ubicación de Azure Blob Storage está configurada como origen de datos externo.

--> Optional - a MASTER KEY is not required if a DATABASE SCOPED CREDENTIAL is not required because the blob is configured for public (anonymous) access!
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'YourStrongPassword1';
GO
--> Optional - a DATABASE SCOPED CREDENTIAL is not required because the blob is configured for public (anonymous) access!
CREATE DATABASE SCOPED CREDENTIAL MyAzureBlobStorageCredential 
WITH IDENTITY = 'Managed Identity';
-- NOTE: Make sure you have granted Storage Bob Data Contributor RBAC on storage to provides read/write access to the managed identity for the necessary Azure Blob Storage containers.
CREATE EXTERNAL DATA SOURCE MyAzureBlobStorage
WITH ( TYPE = BLOB_STORAGE,
          LOCATION = 'https://****************.blob.core.windows.net/invoices'
          , CREDENTIAL= MyAzureBlobStorageCredential --> CREDENTIAL is not required if a blob is configured for public (anonymous) access!
);
BULK INSERT Sales.Invoices
FROM 'inv-2017-12-08.csv'
WITH (DATA_SOURCE = 'MyAzureBlobStorage');

Importante

La identidad administrada solo se aplica a Azure SQL. SQL Server no admite identidades administradas.

Importante

Azure SQL solo admite la lectura mediante Azure Blob Storage.

G. Importar datos desde un archivo en Azure Blob Storage y especificar un archivo de error

En este ejemplo se muestra cómo cargar datos desde un archivo CSV en una ubicación de Azure Blob Storage, que se ha configurado como un origen de datos externo, y también cómo especificar un archivo de error. Necesitará una credencial de ámbito de base de datos que use una firma de acceso compartido. Si se ejecuta en Azure SQL Database, la opción ERRORFILE debe ir acompañada de ERRORFILE_DATA_SOURCE; de lo contrario, la importación podría presentar un error de permisos. El archivo especificado en ERRORFILE no debe existir en el contenedor.

BULK INSERT Sales.Invoices
FROM 'inv-2017-12-08.csv'
WITH (
         DATA_SOURCE = 'MyAzureInvoices'
         , FORMAT = 'CSV'
         , ERRORFILE = 'MyErrorFile'
         , ERRORFILE_DATA_SOURCE = 'MyAzureInvoices');

Para ver ejemplos completos de BULK INSERT, incluido cómo configurar la credencial y el origen de datos externo, vea Ejemplos de acceso masivo a datos en Azure Blob Storage.

Más ejemplos

Se proporcionan otros ejemplos de BULK INSERT en estos artículos:

Consulte también