Bonjour,

J’ai un problème sur un logiciel comptable qui gère chaque dossier client comme une base de données.
Il y a plusieurs choses dans ce logiciel que je gère de manière globale, c’est à dire que j’ai un dossier qui sert de template et que j’aimerai copier sur tous les autres clients.
De plus, pour ne pas compliquer la chose, un dossier comptable a forcément des données annuelles et ce logiciel gère chaque année comptable sur une table différente.
Exemple : La liste des écritures de l’année 2015 d’un client X sera une table ClientX..Historic01.

Bien sur mon dossier template gère des cas pour l’année 2015 mais aussi d’autres cas pour d’autres années.

Bref, pour réaliser les requêtes qui mettent à jour mes dossiers clients, je ne trouve pas d’autres moyens que de réaliser des boucles pour construire mes requêtes en chaînes de caractères et pour savoir quel dossier client affecter...

Ce code marche mais je ne l'exécute pas pour plus d'une dizaine de dossier sinon ça prend beaucoup trop de temps.

Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
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
declare @i int 
declare @j int
declare @Client varchar(500) 
 
declare @numrows int 
declare @numexo int
 
declare @request as varchar(max) 
 
declare @LogicielDB as varchar(max)
set @LogicielDB = 'Client%'
 
drop table ListeClientDB 
create table ListeClientDB (idx int Primary Key IDENTITY(1,1),name varchar(100), nbExo int) 
 
DECLARE @Logiciel_table TABLE (
    idx int Primary Key IDENTITY(1,1) 
    , Client_id nvarchar(128) ) 
 
-- Remplit @Logiciel_table avec toutes les DBs concernées par mon logiciel.
INSERT @Logiciel_table   
select name from sys.databases where name like @LogicielDB
 
-- Ici on parcours chaque DB pour en filtrer certain dossier sur base de règle métier...   
SET @i = 1 
SET @numrows = (SELECT COUNT(Client_id) FROM @Logiciel_table) 
IF @numrows > 0 
    WHILE (@i <= @numrows)
    BEGIN 
 
        SET @Client = (SELECT Client_id FROM @Logiciel_table WHERE idx = @i) 
        select @request = 'insert into ListeClientDB select '''+@Client+''', 0 from ' + @Client + '.dbo.d_acctgeneral where generalid = ''112'' and wordingfr = ''Primes de fusion'''
        --select @request = @request + @Client
		exec(@request) 
	    --select(@request)
 
        -- increment counter for next Client
        SET @i = @i + 1 
    END 
 
-- Ici, on compte le nombre d'exercice sur chaque dossier (nombre de table ''A_%AParam'' ou % est le numéro de l'année)
SET @i = 1 
SET @numrows = (SELECT COUNT(name) FROM ListeClientDB) 
IF @numrows > 0 
    WHILE (@i <= @numrows) 
    BEGIN 
 
        SET @Client = (SELECT name FROM ListeClientDB WHERE idx = @i) 
        select @request = 'update ListeClientDB set nbExo = (select COUNT(T.name) from ' + @Client + '.sys.tables T where T.name like ''A_%AParam'') from ListeClientDB L where L.name = ''' + @Client + '''' 
                exec(@request) 
        -- increment counter for next Year
        SET @i = @i + 1 
    END
 
-- Affichage pour le suivi
select * from ListeClientDB 
 
-- Vidage puis copie des tables à copier du template
SET @i = 1 
SET @numrows = (SELECT COUNT(name) FROM ListeClientDB) 
IF @numrows > 0 
    WHILE (@i <= @numrows) 
    BEGIN 
        SET @Client = (SELECT name FROM ListeClientDB WHERE idx = @i) 
        select @request = 'delete ' + @Client + '..D_BilanCustom'
        exec(@request) 
 
        select @request = ''
 
		-- Parcours de chaque année comptable du client pour copié l'année concerné du template
        SET @j = 0 
		SET @numexo = (SELECT nbExo FROM ListeClientDB where name = @Client) 
		IF @numexo > 0 
			WHILE (@j < @numexo) 
			BEGIN 
        		select @request = @request + ' insert into ' + @Client + '..D_BilanCustom ([BilanID],[AcctingYear],...) select [BilanID],' + convert(varchar,@j) + ',... ' +
				'from Client1813..D_BilanCustom B inner join ' + @Client + '..A_' + right('0'+convert(varchar,@j),2) + '_AParam A on 1 = 1
				where B.AcctingYear = case when A.AcctingYear <= ''2013'' then 0 else 1 end'
-- Permet de diviser l'ajout des bilans pour avant 2014 et après 2014 (l'année 2013 = 0 et 2014 = 1 dans le dossier 1813)
 
				-- increment counter for next Year
				SET @j = @j + 1 
			END 
 
        exec(@request) 
        --select(@request) 
        -- increment counter for next Year
        SET @i = @i + 1 
    END

  1. Pour résumer ce code, je récupère les DB client du logiciel dans une table
  2. Je parcours la table pour supprimer certains clients hors scope
  3. Je reparcours la table pour compter le nombre d'années comptables de chaque client (et j'update la table)
  4. Et enfin je parcours chaque clients de la table, je vide la table que je veux updaté et pour chaque année comptable, je copie de mon template


Voilà en gros ce que fais l'algo.

On m'a dit un jour que faire un while ou autres en SQL, c'est le mal (SQLpro si tu te reconnais ) et je suis d'accord, mais pour ce cas précis, comment faire ?