Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Administration
Administration Forum d'entraide sur l'administration du dataserver, via SSM ou ligne de commande, les tables système, ...
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 07/06/2004, 10h15   #1
Candidat au titre de Membre du Club
 
Inscription : mars 2004
Messages : 24
Détails du profil
Informations forums :
Inscription : mars 2004
Messages : 24
Points : 11
Points : 11
Par défaut restore filelistonly

Bonjour tout le monde

Pour mon script de restauration j'ai besoin de faire un restore filelistonly.
En effet il faut que je récupére le nom du fichier de données pour restaurer mes bases.
Le problème est que certains fichiers de données finissent par _Dat et d'autres par _Data !!

restore filelistonly permet de connaître le vrai nom de chaque fichier de données. En effet il renvoie un jeu de résultats avec le premier champ 'LogicalName' qui concerne les noms des fichiers de données et de logs.
Voici ma ligne :
Code :
restore filelistonly FROM disk='c:\backup\MA_BASE
Il faut que je puisse exploiter ce résultat et le mettre dans une varialbe mais je ne sais pas comment faire.

Visiblement ce n'est pas possible d'utiliser un curseur.

Si quelqu'un peut me dire comment récupérer la valeur ce champ pour l'utiliser dans mon restore database, ça m'aiderait beucoup.

Merci
Nicolas
nic_moq est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2004, 16h37   #2
Candidat au titre de Membre du Club
 
Inscription : mars 2004
Messages : 24
Détails du profil
Informations forums :
Inscription : mars 2004
Messages : 24
Points : 11
Points : 11
Par défaut petites précisions

Bon je n'ai peut être pas été très clair.

J'ai un script qui sauvegarde automatiquement les bases d'un serveur et met les fichiers de sauvegarde dans un répertoire.

J'en ai un autre qui restore automatiquement ces bases en fonction du répertoire dans lequel se trouvent les fichiers de sauvegarde.

le problème est au niveau de la commande RESTORE.

Code :
1
2
3
4
5
6
7
8
9
10
11
        restore DATABASE @database_name
			FROM disk=@path_name
			WITH 
			/*on indique le nouvel emplacement du fichier de données*/
			move @database_data 
			TO @database_data_path,
			/*on indique le nouvel emplacement du fichier de log*/
			move @database_log
			TO @database_log_path,
			/*si la base existe déjà, on la supprime et on la recrée*/
			REPLACE
Le problème est au niveau de la variable @database_data qui contient normalement le nom de la base + _Data.
exemple : Gestion_Data.
Pour l'obtenir, c'est simple, je concaténe le nom de ma base de donnée (déjà stocké dans la variable @database_name) avec _Data.
exemple :
Code :
SET @database_data = @database_name + '_data
[/code].

Le problème et que certain fichiers de données finissent par _Dat au lieu de _Data.
Donc le script ne marche pas pour les bases dont le fichier finit par _Dat
Il faut donc que j'aille chercher directement le nom du fichier de données au lieu de le fabriquer.

c'est pour ça que j'ai pensé au restore filelistonly qui renvoie bien le nom du fichier de données mais je ne sait pas comment le récupérer.

J'ai aussi pensé à stocker les nom des fichiers de données dans le script de sauvegarde soit dans un fichier soit dans une table temporaire.

Mais je ne vois pas trop comment faire.

Si quelqu'un a compris mon charrabia et à une idée ça m'aiderait beaucoup

Merci d'avence
Nicolas
nic_moq est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2004, 17h42   #3
Membre éclairé
 
Inscription : août 2002
Messages : 355
Détails du profil
Informations forums :
Inscription : août 2002
Messages : 355
Points : 355
Points : 355
Slt,

J'ai ecrit il ya quelques temps une procedure qui fait cela, voila le code, tu peux t'en inspirer :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
 
DROP Procedure RestaurationAutomatique
go
 
CREATE Procedure RestaurationAutomatique 
  @evchBase varchar(100),
  @evchFichierBackup varchar(1000),
  @eintDebug integer = 0
AS
 
SET nocount ON
 
Declare @vchData AS varchar(100)
Declare @vchLog AS varchar(100)
Declare @vchFichierData AS varchar(1000)
Declare @vchFichierLog AS varchar(1000)
 
 
IF @evchBase IS NULL AND @evchFichierBackup IS NULL
  RETURN
 
-- kill de toutes les connexions sur la base cible
CREATE TABLE #Connections
(
SPID int
)
 
INSERT INTO  #Connections
SELECT p.spid
FROM master.dbo.sysprocesses p (nolock)
JOIN master..sysdatabases d (nolock) ON p.dbid = d.dbid
WHERE d.[name] = @evchBase
 
Declare @vchSQLText varchar(200), @intSPID int
 
While 1 = 1
Begin
 
	SELECT top 1 @intSPID = SPID
	FROM  #Connections
	WHERE SPID > IsNull(@intSPID, 0) 
	ORDER BY SPID ASC
 
	IF @@RowCount = 0
		Break
 
	SET @vchSQLText = 'Kill ' + Convert(varchar(10), @intSPID)
 
	Exec( @vchSQLText )				
 
End
 
DROP TABLE #Connections
 
-- recuperation nom des fichiers logiques
 
CREATE TABLE #tmpFicLogiques
(
LogicalName varchar(100),
PhysicalName varchar(1000),
Type varchar(5),
FileGroupName varchar(30),
[Size] decimal,
[MaxSize] decimal
)
 
INSERT INTO #tmpFicLogiques (LogicalName,PhysicalName,Type,FileGroupName,[Size],[MaxSize])
exec('RESTORE FILELISTONLY FROM  DISK = N''' + @evchFichierBackup + ''' WITH  FILE = 1')
 
SELECT @vchData = LogicalName FROM #tmpFicLogiques where Type = 'D'
SELECT @vchLog = LogicalName FROM #tmpFicLogiques where Type = 'L'
 
DROP TABLE #tmpFicLogiques
 
IF @vchData IS NULL OR @vchLog IS NULL 
begin
  Print 'Erreur noms logiques invalides'
  RETURN
end
 
-- recuperation des infos de fichier physiques
 
CREATE TABLE #tmpFichiersPhysiques
(
  PhysicalName varchar(1000),
  STATUS       int
)
 
INSERT INTO #tmpFichiersPhysiques (PhysicalName, Status)
 
exec('select filename, usage = (case status & 0x40 when 0x40 then 0 else 1 end) from ' + @evchBase + '..sysfiles')
 
IF @eintDebug =  1 SELECT * FROM #tmpFichiersPhysiques
 
SELECT @vchFichierData = LTrim(Rtrim(PhysicalName)) FROM #tmpFichiersPhysiques where Status = 1
SELECT @vchFichierLog = LTrim(Rtrim(PhysicalName)) FROM #tmpFichiersPhysiques where Status = 0
 
IF @vchFichierData IS NULL OR @vchFichierLog IS NULL 
begin
  Print 'Erreur noms physiques invalides'
  RETURN
end
 
DROP TABLE #tmpFichiersPhysiques
 
-- lance la restauration de la base
 
declare @vchSQL varchar(8000)
 
SET @vchSQL = 'RESTORE DATABASE [' +  @evchBase + '] FROM  DISK = N''' + @evchFichierBackup + 
''' WITH  FILE = 1,  UNLOAD ,  STATS = 10,  RECOVERY ,  REPLACE ,' +
' MOVE N'''+@vchData+''' TO  N'''+@vchFichierData+''',  
MOVE N'''+@vchLog+''' TO N'''+@vchFichierLog+''''
 
--select @vchSQL
 
IF @eintDebug = 0 exec (@vchSQL)
else SELECT @vchSQL


a+
__________________
One ring to rule them all,
One ring to find them,
One ring to bring them all
And in the darkness bind them.
Gandalf Le Blanc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/06/2004, 09h29   #4
Candidat au titre de Membre du Club
 
Inscription : mars 2004
Messages : 24
Détails du profil
Informations forums :
Inscription : mars 2004
Messages : 24
Points : 11
Points : 11
Par défaut Merci

Merci Gandalf, c'est exactement ce que je voulais !!!

A marche niquel maintenant

@ bientôt
Nicolas
nic_moq est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/04/2010, 17h33   #5
Invité de passage
 
Inscription : mai 2009
Messages : 2
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : mai 2009
Messages : 2
Points : 2
Points : 2
Il sera necessaire de rajouter des bloc begin try afin de rendre cette procedure plus exploitable

Citation:
Envoyé par Gandalf Le Blanc Voir le message
Slt,

J'ai ecrit il ya quelques temps une procedure qui fait cela, voila le code, tu peux t'en inspirer :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
 
DROP Procedure RestaurationAutomatique
go
 
CREATE Procedure RestaurationAutomatique 
  @evchBase varchar(100),
  @evchFichierBackup varchar(1000),
  @eintDebug integer = 0
AS
 
SET nocount ON
 
Declare @vchData AS varchar(100)
Declare @vchLog AS varchar(100)
Declare @vchFichierData AS varchar(1000)
Declare @vchFichierLog AS varchar(1000)
 
 
IF @evchBase IS NULL AND @evchFichierBackup IS NULL
  RETURN
 
-- kill de toutes les connexions sur la base cible
CREATE TABLE #Connections
(
SPID int
)
 
INSERT INTO  #Connections
SELECT p.spid
FROM master.dbo.sysprocesses p (nolock)
JOIN master..sysdatabases d (nolock) ON p.dbid = d.dbid
WHERE d.[name] = @evchBase
 
Declare @vchSQLText varchar(200), @intSPID int
 
While 1 = 1
Begin
 
	SELECT top 1 @intSPID = SPID
	FROM  #Connections
	WHERE SPID > IsNull(@intSPID, 0) 
	ORDER BY SPID ASC
 
	IF @@RowCount = 0
		Break
 
	SET @vchSQLText = 'Kill ' + Convert(varchar(10), @intSPID)
 
	Exec( @vchSQLText )				
 
End
 
DROP TABLE #Connections
 
-- recuperation nom des fichiers logiques
 
CREATE TABLE #tmpFicLogiques
(
LogicalName varchar(100),
PhysicalName varchar(1000),
Type varchar(5),
FileGroupName varchar(30),
[Size] decimal,
[MaxSize] decimal
)
 
INSERT INTO #tmpFicLogiques (LogicalName,PhysicalName,Type,FileGroupName,[Size],[MaxSize])
exec('RESTORE FILELISTONLY FROM  DISK = N''' + @evchFichierBackup + ''' WITH  FILE = 1')
 
SELECT @vchData = LogicalName FROM #tmpFicLogiques where Type = 'D'
SELECT @vchLog = LogicalName FROM #tmpFicLogiques where Type = 'L'
 
DROP TABLE #tmpFicLogiques
 
IF @vchData IS NULL OR @vchLog IS NULL 
begin
  Print 'Erreur noms logiques invalides'
  RETURN
end
 
-- recuperation des infos de fichier physiques
 
CREATE TABLE #tmpFichiersPhysiques
(
  PhysicalName varchar(1000),
  STATUS       int
)
 
INSERT INTO #tmpFichiersPhysiques (PhysicalName, Status)
 
exec('select filename, usage = (case status & 0x40 when 0x40 then 0 else 1 end) from ' + @evchBase + '..sysfiles')
 
IF @eintDebug =  1 SELECT * FROM #tmpFichiersPhysiques
 
SELECT @vchFichierData = LTrim(Rtrim(PhysicalName)) FROM #tmpFichiersPhysiques where Status = 1
SELECT @vchFichierLog = LTrim(Rtrim(PhysicalName)) FROM #tmpFichiersPhysiques where Status = 0
 
IF @vchFichierData IS NULL OR @vchFichierLog IS NULL 
begin
  Print 'Erreur noms physiques invalides'
  RETURN
end
 
DROP TABLE #tmpFichiersPhysiques
 
-- lance la restauration de la base
 
declare @vchSQL varchar(8000)
 
SET @vchSQL = 'RESTORE DATABASE [' +  @evchBase + '] FROM  DISK = N''' + @evchFichierBackup + 
''' WITH  FILE = 1,  UNLOAD ,  STATS = 10,  RECOVERY ,  REPLACE ,' +
' MOVE N'''+@vchData+''' TO  N'''+@vchFichierData+''',  
MOVE N'''+@vchLog+''' TO N'''+@vchFichierLog+''''
 
--select @vchSQL
 
IF @eintDebug = 0 exec (@vchSQL)
else SELECT @vchSQL


a+
harriga.rabie est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/04/2010, 00h02   #6
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 959
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 959
Points : 17 791
Points : 17 791
La procédure de Gandalf Le Blanc au niveau des KILL est tout à fait catastrophique.... C'est hélas un script que l'on voit régulièrement sur le net.

Le problème est qu'il n'empêche nullement qu'un utilisateur se reconnecte. Or quand un sait qu'un KILL fait un rollback et qu'un ROLLBACK peut prendre du temps, il est certain qu'en production cela sera épouvantable.

De plus Gandalf utilise des appels à des tables système qui n'existe plus depuis la version 2005, soit 2 versions de retard, exemple : sysprocesses et sysdatabases !

C'est d'autant plus navrant qu'il existe une commande directe et immédiate pour faire tout cela et depuis au moins la version 2000 de SQL Server :
Code :
ALTER DATABASE <mabase> SET SINGLE_USER WITH ROLLBACK IMMEDIATE
Elle permet à la connexion courante de reprendre la main sur la base si celle-ci s'est préalablement positionnée dedans.
Ensuite on peut faire ce que l'on veut comme un ALTER DATABASE <mabase> SET OFFLINE suivi par exemple d'un RESTAURE avec l'option REPLACE !
Enfin, la fin du script est navrante aussi car truffée d'erreurs :
1) on suppose qu'il n'y a toujours qu'un seule fichier de sauvegarde dans le device (FILE = 1) ce qui peut être faux.
2) on suppose qu'il n'y a qu'un seul fichier de données et qu'un seul fichier du JT ce qui est tout aussi probablement faux...

Bref, un petit cours d'administration serait un plus !

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 10h08.


 
 
 
 
Partenaires

Hébergement Web