Utiliser BULK INSERT ou OPENROWSET(BULK...) pour importer des données dans SQL Server

S’applique à : SQL Server Azure SQL Database Azure SQL Managed Instance

Cet article explique comment utiliser l'instruction Transact-SQL BULK INSERT et l'instruction INSERT...SELECT * FROM OPENROWSET(BULK...) pour importer en masse des données d'un fichier de données dans une table SQL Server ou Azure SQL Database. Cet article décrit aussi des considérations relatives à la sécurité concernant l’utilisation de BULK INSERT et OPENROWSET(BULK...), et l’utilisation de ces méthodes pour l’importation en bloc à partir d’une source de données distante.

Remarque

Quand vous utilisez BULK INSERT ou OPENROWSET(BULK...), il est important de comprendre la manière dont la version de SQL Server gère l'usurpation d'identité. Pour plus d'informations, consultez « Considérations sur la sécurité» plus loin dans cette rubrique.

Instruction BULK INSERT

BULK INSERT charge les données d'un fichier de données dans une table. Cette fonctionnalité est similaire à celle fournie par l'option in de la commande bcp, mais le fichier de données est lu par le processus SQL Server. Pour une description de la syntaxe de BULK INSERT, voir BULK INSERT (Transact-SQL).

Exemples BULK INSERT

Fonction OPENROWSET (BULK…)

Le fournisseur d'ensembles de lignes en bloc OPENROWSET est accessible en appelant la fonction OPENROWSET et en spécifiant l'option BULK. La fonction OPENROWSET(BULK...) vous permet d’accéder aux données distantes en vous connectant à une source de données distante (un fichier de données) par l’intermédiaire d’un fournisseur OLE DB.

Pour importer en bloc des données, appelez OPENROWSET(BULK...) à partir d’une clause SELECT...FROM dans une instruction INSERT. La syntaxe de base pour l'importation en bloc de données est la suivante :

INSERT ... SELECT * FROM OPENROWSET(BULK...)

Lorsqu'elle apparaît dans une instruction INSERT, OPENROWSET(BULK...) prend en charge les indicateurs de table. En plus des indicateurs de table normaux, tels que TABLOCK, la clause BULK peut accepter les indicateurs de table spécialisés suivants : IGNORE_CONSTRAINTS (ignore uniquement les contraintes CHECK), IGNORE_TRIGGERS, KEEPDEFAULTS et KEEPIDENTITY. Pour plus d’informations, consultez Indicateurs de table (Transact-SQL).

Pour plus d'informations sur les autres utilisations de l'option BULK, voir OPENROWSET (Transact-SQL).

Exemples de l'instruction INSERT...SELECT S* FROM OPENROWSET (BULK...)

Considérations de sécurité

Si un utilisateur a recours à une connexion SQL Server , le profil de sécurité du compte du processus SQL Server est alors utilisé. Une connexion via l’authentification SQL Server ne peut pas être authentifiée en dehors du Moteur de base de données. Par conséquence, lorsqu'une commande BULK INSERT est initiée par une connexion via l'authentification SQL Server, la connexion aux données s'effectue à l'aide du contexte de sécurité du compte du processus SQL Server (compte utilisé par le service de moteur de base de données SQL Server).

Pour pouvoir lire les données sources, vous devez octroyer au compte utilisé par le moteur de base de données SQL Server l'accès aux données sources. Par opposition, si un utilisateur SQL Server s'est connecté via l'authentification Windows, il peut lire uniquement les fichiers accessibles par le compte d'utilisateur, indépendamment du profil de sécurité du processus SQL Server .

Prenons l'exemple d'un utilisateur qui s'est connecté à une instance de SQL Server à l'aide de l'authentification Windows. Pour que cet utilisateur puisse utiliser BULK INSERT ou OPENROWSET en vue d'importer les données d'un fichier dans une table SQL Server, le compte d'utilisateur nécessite des droits d'accès en lecture au fichier de données. En bénéficiant de droits accès au fichier de données, l'utilisateur peut importer les données du fichier dans une table même si le processus SQL Server n'a pas l'autorisation d'accéder au fichier. L'utilisateur n'est pas obligé d'accorder au processus SQL Server une autorisation d'accès au fichier.

SQL Server et Microsoft Windows peuvent être configurés afin de permettre à une instance de SQL Server de se connecter à une autre instance de SQL Server en transmettant les informations d'un utilisateur Windows authentifié. Ce procédé est appelé emprunt d'identité ou délégation. Il importe de comprendre comment la version de SQL Server gère les aspects de sécurité en matière d'emprunt d'identité lorsque vous utilisez l'instruction BULK INSERT ou OPENROWSET. L'emprunt d'identité permet au fichier de données de résider sur un ordinateur différent du processus SQL Server ou de l'utilisateur. Par exemple, si un utilisateur sur Ordinateur_A a accès à un fichier de données sur Ordinateur_B, et que la délégation des informations d'identification a été correctement définie, l'utilisateur peut se connecter à une instance de SQL Server s'exécutant sur Ordinateur_C, accéder au fichier de données sur Ordinateur_B, et importer les données en bloc de ce fichier dans une table résidant sur Ordinateur_C.

Importation en bloc dans SQL Server à partir d’un fichier de données distant

Pour utiliser BULK INSERT ou INSERT...SELECT * FROM OPENROWSET(BULK...) pour effectuer l'importation en bloc de données à partir d'un autre ordinateur, le fichier de données doit être partagé entre les deux ordinateurs. Pour spécifier un fichier de données partagé, utilisez son nom selon la convention de dénomination universelle (UNC), qui prend la forme générale suivante : \\Nom du serveur\Nom de partage\ Chemin\Nom du fichier. En outre, le compte utilisé pour accéder au fichier de données doit avoir reçu les autorisations requises pour lire le fichier sur le disque distant.

Par exemple, l'instruction BULK INSERT ci-dessous importe en bloc des données dans la table SalesOrderDetail de la base de données AdventureWorks à partir d'un fichier de données nommé newdata.txt. Ce fichier de données réside dans un dossier partagé nommé \dailyorders , dans un répertoire partagé du réseau nommé salesforce , sur un système nommé computer2.

BULK INSERT AdventureWorks2022.Sales.SalesOrderDetail
   FROM '\\computer2\salesforce\dailyorders\neworders.txt';

Remarque

Cette restriction ne s'applique pas à l'utilitaire bcp, car le fichier est lu par le client indépendamment de SQL Server.

Importation en bloc à partir du stockage d’objets blob Azure

Quand vous importez des données du stockage Blob Azure qui ne sont pas publiques (accès anonyme), créez une connexion DATABASE SCOPED CREDENTIAL basée sur une clé SAS chiffrée avec une CLÉ PRINCIPALE, puis créez une source de base de données externe à utiliser dans votre commande BULK INSERT.

Vous pouvez également créer un DATABASE SCOPED CREDENTIAL basé sur MANAGED IDENTITY pour autoriser les demandes d'accès aux données dans des comptes de stockage non publics. Quand MANAGED IDENTITY est utilisé, le Stockage Azure doit accorder des autorisations à l’identité managée de l’instance en ajoutant le rôle de contrôle d’accès en fonction du rôle (RBAC) Azure intégré Contributeur aux données Blob du stockage. Ce rôle fournit un accès en lecture/écriture à l’identité managée sur les conteneurs Stockage Blob Azure nécessaires. Les instances Azure SQL Managed Instance ont une identité managée affectée par le système, et peuvent également avoir une ou plusieurs identités managées affectées par l’utilisateur. Vous pouvez utiliser aussi bien des identités managées affectées par le système que des identités managées affectées par l’utilisateur pour autoriser les demandes. Pour l'autorisation, l'identité default de la Managed Instance est utilisée (c'est-à-dire l'identité managée affectée par l'utilisateur principal ou l'identité managée affectée par le système si l'identité managée affectée par l'utilisateur n'est pas spécifiée).

Important

L’identité managée s’applique uniquement à Azure SQL. SQL Server ne prend pas en charge l’identité managée.

Remarque

N’utilisez pas de transaction explicite ou vous recevrez une erreur 4861.

Utilisation de BULK INSERT

L’exemple suivant montre comment utiliser la commande BULK INSERT pour charger des données à partir d’un fichier CSV dans un emplacement de stockage d’objets blob Azure sur lequel vous avez créé une clé SAS. L’emplacement du stockage Blob Azure est configuré comme source de données externe. Ceci nécessite des informations d’identification délimitées à la base de données avec une signature d’accès partagé chiffrée à l’aide d’une clé principale dans la base de données utilisateur.

--> 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');

L’exemple suivant montre comment utiliser la commande BULK INSERT pour charger les données d’un fichier CSV à un emplacement de Stockage Blob Azure qui utilise l’identité managée. L’emplacement du stockage Blob Azure est configuré comme source de données externe.

--> 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');

Important

L’identité managée s’applique uniquement à Azure SQL. SQL Server ne prend pas en charge l’identité managée.

Azure SQL Database ne prend pas en charge la lecture dans des fichiers Windows.

Utilisation de OPENROWSET

L’exemple suivant montre comment utiliser la commande OPENROWSET pour charger des données à partir d’un fichier CSV dans un emplacement de stockage Blob Azure sur lequel vous avez créé une clé SAS. L’emplacement du stockage Blob Azure est configuré comme source de données externe. Ceci nécessite des informations d’identification délimitées à la base de données avec une signature d’accès partagé chiffrée à l’aide d’une clé principale dans la base de données utilisateur.

--> 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!
);

INSERT INTO achievements with (TABLOCK) (id, description)
SELECT * FROM OPENROWSET(
   BULK  'csv/achievements.csv',
   DATA_SOURCE = 'MyAzureBlobStorage',
   FORMAT ='CSV',
   FORMATFILE='csv/achievements-c.xml',
   FORMATFILE_DATA_SOURCE = 'MyAzureBlobStorage'
    ) AS DataFile;

Important

Azure SQL Database ne prend pas en charge la lecture dans des fichiers Windows.