Microsoft SQL Server - Import / Restauration d'une base
- 1. Introduction et formats acceptes
- 2. Prerequis et inspection du fichier
- 3. Restaurer un .bak (RESTORE DATABASE)
- 4. Importer un .sql (script T-SQL)
- 5. Importer un CSV / TSV (bcp)
- 6. BULK INSERT en T-SQL
- 7. Importer un .bacpac (SqlPackage)
- 8. Attacher des fichiers MDF / LDF
- 9. Verifications post-import
- 10. Depannage courant
1. Introduction et formats acceptes
Trois grands chemins d'import existent vers MSSQL :
| Format source | Commande | Niveau |
|---|---|---|
.bak | RESTORE DATABASE | Base entiere (la plus rapide) |
.sql | sqlcmd -i ou execution dans SSMS | DDL + DML, lent mais portable |
.csv / .tsv | bcp in ou BULK INSERT | Une table (apres CREATE TABLE) |
.bacpac | SqlPackage /Action:Import | Base entiere avec schema + data compresse |
.mdf + .ldf | CREATE DATABASE ... FOR ATTACH | Fichiers physiques directs |
- J'ai un
.bak? → Section 3 (RESTORE DATABASE) - J'ai un
.sql? → Section 4 - J'ai des CSV ? → Sections 5 / 6
- J'ai des fichiers
.mdf/.ldfseuls ? → Section 8
2. Prerequis et inspection du fichier
2.1 Droits requis
RESTORE DATABASE: roledbcreatorousysadminBULK INSERT/bcp in:ADMINISTER BULK OPERATIONS+INSERTsur la table- Le compte service SQL Server doit pouvoir lire le fichier (.bak / CSV) sur le disque du serveur.
2.2 Inspecter un .bak avant restauration
# Verifier que le fichier est lisible et non corrompu
sqlcmd -S localhost -E -Q "RESTORE VERIFYONLY FROM DISK='D:\backup\MaBase.bak'"
# Voir les jeux de sauvegarde contenus (utile si plusieurs FULL/DIFF dans un meme fichier)
sqlcmd -S localhost -E -Q "RESTORE HEADERONLY FROM DISK='D:\backup\MaBase.bak'"
# Voir les fichiers logiques (noms MDF / LDF) - INDISPENSABLE pour MOVE
sqlcmd -S localhost -E -Q "RESTORE FILELISTONLY FROM DISK='D:\backup\MaBase.bak'"
Le resultat de FILELISTONLY donne par exemple :
LogicalName PhysicalName Type
MaBase D:\Data\MaBase.mdf D
MaBase_log D:\Logs\MaBase_log.ldf L
Notez les LogicalName : ils seront reutilises dans la clause MOVE au moment du RESTORE.
3. Restaurer un .bak (RESTORE DATABASE)
3.1 Restauration simple (memes chemins que la source)
sqlcmd -S localhost -E -Q "RESTORE DATABASE [MaBase] FROM DISK='D:\backup\MaBase.bak' WITH REPLACE, STATS=10"
3.2 Restauration avec relocalisation des fichiers (MOVE)
Cas le plus frequent : restaurer un .bak sur un serveur dont les chemins de stockage sont differents.
sqlcmd -S localhost -E -Q "
RESTORE DATABASE [MaBase]
FROM DISK='D:\backup\MaBase.bak'
WITH
MOVE 'MaBase' TO 'D:\SQL\Data\MaBase.mdf',
MOVE 'MaBase_log' TO 'D:\SQL\Logs\MaBase_log.ldf',
REPLACE,
STATS=10
"
MOVE TO sont evalues cote serveur. Les dossiers doivent exister et etre accessibles en ecriture par le compte de service SQL Server.
3.3 Restaurer sous un autre nom de base
RESTORE DATABASE [MaBase_Test]
FROM DISK='D:\backup\MaBase.bak'
WITH
MOVE 'MaBase' TO 'D:\SQL\Data\MaBase_Test.mdf',
MOVE 'MaBase_log' TO 'D:\SQL\Logs\MaBase_Test_log.ldf',
REPLACE
3.4 Options principales
| Option | Effet |
|---|---|
REPLACE | Ecrase la base existante (sinon erreur si elle existe deja) |
RECOVERY (defaut) | La base est utilisable apres restauration |
NORECOVERY | La base reste en mode "restauration" : permet d'appliquer des DIFF ou des LOG ensuite |
STANDBY = 'fichier_undo.bak' | La base est lisible mais des logs peuvent encore etre appliques |
STATS=10 | Affiche la progression tous les 10% |
CHECKSUM | Verifie l'integrite a la lecture |
FILE=2 | Restaure le 2eme jeu de sauvegarde du fichier (cf. HEADERONLY) |
3.5 Chaine FULL + DIFF + LOG (point-in-time)
-- 1) Restaurer le FULL en NORECOVERY
RESTORE DATABASE [MaBase] FROM DISK='D:\backup\MaBase_FULL.bak'
WITH NORECOVERY, REPLACE;
-- 2) Restaurer le DIFF (toujours NORECOVERY si on enchaine avec un LOG)
RESTORE DATABASE [MaBase] FROM DISK='D:\backup\MaBase_DIFF.bak'
WITH NORECOVERY;
-- 3) Restaurer les LOG, idealement en STOPAT pour un point-in-time
RESTORE LOG [MaBase] FROM DISK='D:\backup\MaBase_LOG.trn'
WITH RECOVERY, STOPAT = '2026-05-21 10:00:00';
3.6 Restauration en script PowerShell
param(
[string]$Server = "localhost",
[string]$BakFile = "D:\backup\MaBase.bak",
[string]$NewDbName = "MaBase",
[string]$DataPath = "D:\SQL\Data",
[string]$LogPath = "D:\SQL\Logs"
)
# 1. Lire FILELISTONLY pour recuperer les LogicalName
$files = & sqlcmd -S $Server -E -h-1 -W -s "|" -Q "SET NOCOUNT ON; RESTORE FILELISTONLY FROM DISK='$BakFile'"
# 2. Construire les clauses MOVE
$moves = @()
foreach ($line in $files) {
if ($line -match "^(\S+)\|(\S+)\|(D|L)\|") {
$logicalName = $matches[1]
$type = $matches[3]
if ($type -eq "D") {
$newPath = Join-Path $DataPath "$NewDbName.mdf"
} else {
$newPath = Join-Path $LogPath "${NewDbName}_log.ldf"
}
$moves += "MOVE '$logicalName' TO '$newPath'"
}
}
# 3. Construire et executer le RESTORE
$moveClause = $moves -join ", "
$restore = "RESTORE DATABASE [$NewDbName] FROM DISK='$BakFile' WITH $moveClause, REPLACE, STATS=10"
Write-Host "Restauration en cours..." -ForegroundColor Cyan
& sqlcmd -S $Server -E -Q $restore
4. Importer un .sql (script T-SQL)
4.1 Pre-requis : creer la base cible
sqlcmd -S localhost -E -Q "CREATE DATABASE [MaBase]"
4.2 Executer le script
# Mode caracteres : utf-8 (UTF-8 BOM)
sqlcmd -S localhost -E -d MaBase -i "D:\backup\MaBase.sql" -f 65001
# Avec auth SQL
sqlcmd -S localhost -U sa -P MotDePasse -d MaBase -i "D:\backup\MaBase.sql"
# En mode silencieux (pas de message intermediaire), log les erreurs
sqlcmd -S localhost -E -d MaBase -i "D:\backup\MaBase.sql" -b -o "D:\backup\import.log"
4.3 Options sqlcmd utiles
| Option | Effet |
|---|---|
-i fichier | Fichier d'entree (script SQL) |
-o fichier | Fichier de sortie (log) |
-d base | Base par defaut |
-b | Quitte avec un code d'erreur si echec (utile en script) |
-f 65001 | Code page UTF-8 |
-r 1 | Redirige les erreurs vers stderr |
-V 16 | Severite minimum pour erreur (defaut 0) |
-x | Desactive l'interpretation des variables |
4.4 Gros fichier .sql (> 1 Go)
Pour les exports volumineux, decouper le script ou utiliser osql (deprecie mais plus tolerant) :
# Lire en streaming avec PowerShell
Get-Content D:\backup\big.sql -ReadCount 0 | sqlcmd -S localhost -E -d MaBase
# Alternative : passer par -i (sqlcmd gere bien jusqu'a plusieurs Go)
sqlcmd -S localhost -E -d MaBase -i "D:\backup\big.sql" -b
GO. Ils sont compris par sqlcmd mais pas par tous les executeurs SQL (.NET SqlCommand, par exemple). Utiliser sqlcmd -i ou SSMS.
5. Importer un CSV / TSV (bcp)
5.1 Creer la table cible
CREATE TABLE dbo.Clients (
Id INT PRIMARY KEY,
Nom NVARCHAR(100),
Email NVARCHAR(200),
Actif BIT
);
5.2 Import avec bcp
# CSV avec virgule, ignore la 1ere ligne (header) avec -F 2
bcp MaBase.dbo.Clients in "D:\import\clients.csv" -c -t"," -r"\n" -F 2 -S localhost -T
# Avec UTF-8 (eviter les pb d'accents)
bcp MaBase.dbo.Clients in "D:\import\clients.csv" -c -t"," -F 2 -C 65001 -S localhost -T
# Avec auth SQL
bcp MaBase.dbo.Clients in "D:\import\clients.csv" -c -t"," -F 2 -S localhost -U sa -P MotDePasse
5.3 Options bcp in
| Option | Effet |
|---|---|
-F n | Commencer a la ligne n (mettre 2 si CSV a une ligne d'entete) |
-L n | Derniere ligne a importer |
-b 10000 | Taille de batch (commit toutes les n lignes) |
-e fichier.err | Fichier de log des lignes en erreur |
-m 100 | Stoppe apres 100 erreurs |
-k | Conserve les valeurs NULL (n'utilise pas les DEFAULT) |
-E | Garde les valeurs IDENTITY de la source (IDENTITY_INSERT) |
-h "TABLOCK" | Verrouille la table : import beaucoup plus rapide |
5.4 Fichier format (.fmt) pour structures complexes
# Generer un fichier format
bcp MaBase.dbo.Clients format nul -c -t"," -f D:\import\clients.fmt -S localhost -T
# L'utiliser pour l'import
bcp MaBase.dbo.Clients in D:\import\clients.csv -f D:\import\clients.fmt -S localhost -T
-b 50000 -h "TABLOCK,ORDER(Id ASC)". Gain typique : x5 a x10.
6. BULK INSERT en T-SQL
Alternative interne a bcp : execution depuis n'importe quel client (SSMS, sqlcmd, application).
BULK INSERT dbo.Clients
FROM 'D:\import\clients.csv'
WITH (
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
FIRSTROW = 2, -- ignore la 1ere ligne (header)
CODEPAGE = '65001', -- UTF-8
DATAFILETYPE = 'char',
KEEPNULLS, -- preserve les NULL
TABLOCK, -- accelere
ERRORFILE = 'D:\import\clients.err',
MAXERRORS = 100
);
D:\import\clients.csv doit exister sur le serveur, pas sur le poste client. Pour utiliser un partage : FROM '\\serveur\partage\file.csv' + droits SMB du compte de service.
6.1 OPENROWSET BULK (alternative)
-- Permet de filtrer / transformer avant insertion
INSERT INTO dbo.Clients (Id, Nom, Email)
SELECT Id, Nom, Email
FROM OPENROWSET(
BULK 'D:\import\clients.csv',
FORMATFILE = 'D:\import\clients.fmt',
FIRSTROW = 2
) AS src
WHERE Actif = 1;
7. Importer un .bacpac (SqlPackage)
SqlPackage /Action:Import `
/SourceFile:"D:\import\MaBase.bacpac" `
/TargetServerName:"localhost" `
/TargetDatabaseName:"MaBase_New" `
/TargetTrustServerCertificate:True
Options utiles :
/p:DatabaseEdition=Basic(Azure SQL : edition cible)/p:DatabaseServiceObjective=S1(niveau de service)/p:Storage=File(defaut : fichier ; pour Azure :BlobStorage)
7.1 Importer un .dacpac (schema seulement)
SqlPackage /Action:Publish `
/SourceFile:"D:\import\MaBase.dacpac" `
/TargetServerName:"localhost" `
/TargetDatabaseName:"MaBase_Empty"
8. Attacher des fichiers MDF / LDF
Si vous recevez les fichiers physiques d'une base (.mdf et .ldf) au lieu d'un .bak :
-- Copier d'abord les fichiers dans un dossier accessible par le service SQL
-- Exemple : D:\SQL\Data\MaBase.mdf et D:\SQL\Logs\MaBase_log.ldf
CREATE DATABASE [MaBase]
ON (FILENAME = N'D:\SQL\Data\MaBase.mdf'),
(FILENAME = N'D:\SQL\Logs\MaBase_log.ldf')
FOR ATTACH;
8.1 Attacher sans le LDF (regenere automatiquement)
CREATE DATABASE [MaBase]
ON (FILENAME = N'D:\SQL\Data\MaBase.mdf')
FOR ATTACH_REBUILD_LOG;
ATTACH_REBUILD_LOG ignore les transactions non commitees du LDF original. A utiliser uniquement si le LDF est perdu ou corrompu.
8.2 Detacher (avant deplacement)
USE master;
EXEC sp_detach_db 'MaBase';
-- Puis copier MDF/LDF vers le nouveau serveur
9. Verifications post-import
9.1 Integrite physique de la base
USE MaBase;
DBCC CHECKDB WITH NO_INFOMSGS, ALL_ERRORMSGS;
9.2 Mise a jour des statistiques
USE MaBase;
EXEC sp_updatestats;
9.3 Verifier les utilisateurs orphelins (SID different sur le nouveau serveur)
USE MaBase;
EXEC sp_change_users_login 'Report'; -- Liste les orphelins
-- Reassigner un login existant
EXEC sp_change_users_login 'Update_One', 'mon_user', 'mon_login_sql';
9.4 Verifier la taille et l'espace
USE MaBase;
EXEC sp_spaceused;
-- Par table
SELECT
t.name AS TableName,
SUM(p.rows) AS RowCount,
SUM(a.total_pages) * 8 / 1024.0 AS TotalSizeMB
FROM sys.tables t
JOIN sys.partitions p ON t.object_id = p.object_id
JOIN sys.allocation_units a ON p.partition_id = a.container_id
WHERE p.index_id IN (0, 1)
GROUP BY t.name
ORDER BY TotalSizeMB DESC;
9.5 Reorganiser / Reconstruire les index
-- Reconstruire tous les index de toutes les tables
USE MaBase;
EXEC sp_MSforeachtable 'ALTER INDEX ALL ON ? REBUILD';
10. Depannage courant
| Erreur | Cause | Solution |
|---|---|---|
The media set has 2 family members but only 1 are provided |
Le .bak a ete fait sur plusieurs fichiers (cf. section 3.6 export) | Specifier tous les fichiers : FROM DISK='f1.bak', DISK='f2.bak' |
The backup set holds a backup of a database other than the existing |
Le .bak contient une autre base que celle visee | Ajouter WITH REPLACE |
Restore failed for Server. Exclusive access could not be obtained |
La base cible est en cours d'utilisation | ALTER DATABASE [base] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; puis RESTORE |
The version of the database is greater than the current server |
.bak issu d'une version MSSQL plus recente | Restaurer sur la meme version (ou superieure). Impossible de downgrader. |
RESTORE detected an error on page |
.bak corrompu | RESTORE VERIFYONLY ; sinon refaire le .bak source |
BULK INSERT : Cannot bulk load. The file does not exist |
Chemin evalue cote serveur, pas cote client | Deplacer le fichier sur le serveur ou utiliser un partage UNC accessible par le compte service |
bcp : Conversion failed |
Type CSV incompatible avec le schema (ex: date au format inattendu) | Generer un fichier format .fmt avec bcp ... format nul et le retoucher |
Login failed for user apres restore |
Utilisateur DB orphelin (SID different) | EXEC sp_change_users_login 'Update_One', 'user', 'login' |
-- Lister les sessions
SELECT spid FROM sys.sysprocesses WHERE dbid = DB_ID('MaBase');
-- Tuer une session
KILL 53;
-- Repasser en multi-user
ALTER DATABASE [MaBase] SET MULTI_USER;