Bonjour les as!
Je vais essayer d'être concis et clair:
1. Objectif : Récupérer des informations des serveurs INTEGRALE ligne 500 via des serveurs liés par ODBC et mettre des données issues de requêtes dans une base SQL.
L'application d'origine et une page IIS - ASP aui appelle une SP de SQL.
2. Volumétrie:On parle grosso modo de 26 filiales dont on récupère entre 50.000 et 200.000 lignes à chaque fois.
La base SQL n'éxède pas 400Mb une fois toutes les données intégrées.
3. Méthode:Une procédure stockée avec 2 paramètres en appel (FILIALE + UNE_DATE) fait le travail suivant:
* Je désactive les indexes de mes tables SQL
* On efface les données de la filiale
* On intègre les données de 2 premières tables de l'intégrale dans une seule table SQL (ECRITURES)
* On intègre les données de 3 autres tables INTEG dans SQL
* Je réduis le fichier LOG à sa plus simple expression
4. La SP en elle même:Code :
SET ANSI_NULLS ONSET QUOTED_IDENTIFIER ON
go
ALTER PROCEDURE [dbo].[INTEG_INTERCO]
@SOCANA CHAR(3),
@DATEDEBUT CHAR(10)
AS
--BEGIN TRY--BEGIN TRAN
ALTERINDEX[IX_TB_ECRITURES]ON[dbo].[TB_ECRITURES] DISABLE
ALTERINDEX[IX_TB_COMPTES]ON[dbo].[TB_COMPTES] DISABLE
-- *** Initialisations ****************************************
DECLARE
@ANNEEDEBUT CHAR(4),
@sSQL NVARCHAR(4000),
@TB_INTEG_BRO NVARCHAR(20),
@TB_INTEG_HIS NVARCHAR(20),
@TB_INTEG_PLC NVARCHAR(20),
@TB_INTEG_CLI NVARCHAR(20),
@TB_INTEG_FOU NVARCHAR(20),
@sWHR VARCHAR(300),
@sINSERTSQL NVARCHAR(4000),
@INTEG_ECR_tmp NVARCHAR(4000),
@INTEG_ECR_BRO_tmp NVARCHAR(4000),
@INTEG_ECR_HIS_tmp NVARCHAR(4000)
SET @ANNEEDEBUT = LEFT(@DATEDEBUT,4)SET @TB_INTEG_BRO = 'BROUIL_CPTA_GEN'SET @TB_INTEG_HIS = 'HISTO_CPTA_GENE'SET @TB_INTEG_PLC = 'PLAN_COMPT_GENE'SET @TB_INTEG_CLI = 'CLIENTS'SET @TB_INTEG_FOU = 'FOURNISSEURS'
-- 1. ECRITURES-- 1.a Effacer les donnéesSET @sSQL = 'DELETE TB_ECRITURES
WHERE YEAR(ECR_DATE) >= ' + @ANNEEDEBUT +
' AND ECR_CODE_ANALYTIQUE = ''' + @SOCANA + ''' '
EXECUTE(@sSQL)
PRINT @sSQL
PRINT 'DEL TB_ECRITURES'
-- Condition de filtrage sur la date des écritures:SET @sWHR = ' WHERE YEAR(DAT_ECR) >= ' + @ANNEEDEBUT
DECLARE
@sSQL_INTEG_ECR VARCHAR(300)
-- Définitions SQL pour les écrituresSET @sSQL_INTEG_ECR = 'SELECT NUM_LOT, COD_JRN,
DAT_ECR,
CONCAT(NUM_PIE_DEB, NUM_PIE_FIN) as PIECE,
CLF,
CPT,
SEN_ECR,
MNT_DBT_FRS,
LIB_ECR
FROM '
DECLARE
@sSQL_INTEG_BRO NVARCHAR(4000),
@sSQL_INTEG_HIS NVARCHAR(4000)
SET @sSQL_INTEG_BRO = @sSQL_INTEG_ECR + @TB_INTEG_BRO + @SWHR
SET @sSQL_INTEG_HIS = @sSQL_INTEG_ECR + @TB_INTEG_HIS + @SWHR
SET @sINSERTSQL = 'INSERT INTO TB_ECRITURES
(
ECR_CODE_ANALYTIQUE,
ECR_HISTO_BROUILLARD,
ECR_NUM_LOT,
ECR_JOURNAL,
ECR_DATE,
ECR_PIECE,
ECR_COLLECTIF,
ECR_COMPTE,
ECR_DEBIT,
ECR_CREDIT,
ECR_LIBELLE,
ECR_LETTRAGE,
ECR_MONTANTCOUVERTURE,
ECR_DATELETTRAGE,
ECR_LNK_CPT
)
'
DECLARE
@SQL_ECR_BRO_tmp NVARCHAR(4000),
@SQL_ECR_HIS_tmp NVARCHAR(4000),
@SQL_ECR_tmp NVARCHAR(4000)SET @INTEG_ECR_tmp = ',NUM_LOT ,COD_JRN, CAST(DAT_ECR AS SMALLDATETIME),
PIECE, CLF, CPT + '''',
CASE SEN_ECR
WHEN ''C'' THEN ''0''
ELSE MNT_DBT_FRS
END AS ECR_DEBIT,
CASE SEN_ECR
WHEN ''D'' THEN
''0''
ELSE
MNT_DBT_FRS
END AS ECR_CREDIT,
SUBSTRING(REPLACE(LIB_ECR, CHAR(0), ''''), 1, 30) AS ECR_LIBELLE,
''N/A'' AS ECR_LETTRAGE,
''0'' as ECR_MONTANTCOUVERTURE,
''4501-01-01'' as ECR_DATELETTRAGE,
CASE SUBSTRING(CLF,1,2)
WHEN ''40'' THEN ''FOU''
WHEN ''41'' THEN ''CLI''
ELSE ''PLC''
END AS ECR_LNK_CPT
FROM OPENQUERY'
SET @INTEG_ECR_BRO_tmp = 'SELECT ' +
'''' + @SOCANA + ''', ''BRO'' '
+ @INTEG_ECR_tmp
SET @INTEG_ECR_HIS_tmp = 'SELECT ' +
'''' + @SOCANA + ''', ''HIS'' '
+ @INTEG_ECR_tmp
-- 1.b Intégration des Ecritures-- INSERTION ECRITURES BROUILLARDSET @sSQL = @sINSERTSQL +
@INTEG_ECR_BRO_tmp +
'(INTEGRALE_' + @SOCANA + ',
''' + @sSQL_INTEG_BRO + ''')'
PRINT 'INS ECR_BRO'
EXECUTE(@sSQL)
PRINT @sSQL
-- INSERTION ECRITURES HISTOSET @sSQL = @sINSERTSQL +
@INTEG_ECR_HIS_tmp +
'(INTEGRALE_' + @SOCANA + ',
''' + @sSQL_INTEG_HIS + ''')'
PRINT 'INS ECR HIS: '
EXECUTE(@sSQL)
PRINT @sSQL
-- 2. COMPTES-- 2.a Effacer les données
SET @sSQL = 'DELETE TB_COMPTES WHERE CPT_CODE_ANALYTIQUE ='+@SOCANA
EXECUTE(@sSQL)
PRINT @sSQL
PRINT 'DEL TB_COMPTES'
-------------------------------------------------------------------------------
DECLARE
@sSQL_tmp NVARCHAR(4000),
@sSQL_PLC NVARCHAR(4000),
@INTEG_PLC NVARCHAR(4000)
SET @sINSERTSQL = 'INSERT INTO TB_COMPTES(
CPT_CODE_ANALYTIQUE,
CPT_COMPTE,
CPT_LIBELLE,
CPT_ANALYTIQUE,
CPT_LNK_ECR
)'
SET @sSQL_PLC = @sINSERTSQL +
' SELECT' +
'''' + @SOCANA + ''',
SUBSTRING(CPT_GNR,1,13),
SUBSTRING(ITT_CPT,1,30) ,
SUBSTRING(COD_LBR_1,1,13),
''PLC''
FROM OPENQUERY'
SET @INTEG_PLC = 'SELECT
CPT_GNR,
ITT_CPT,
COD_LBR_1
FROM PLAN_COMPT_GENE'
SET @sSQL = @sSQL_PLC +
'(INTEGRALE_' + @SOCANA + ',
''' + @INTEG_PLC + ''')'
EXECUTE(@sSQL)
PRINT @sSQL
PRINT '# IMPORT PLAN COMPTABLE OK'
SET @sSQL_PLC = @sINSERTSQL +
' SELECT' +
'''' + @SOCANA + ''',
SUBSTRING(COD_CLT,1,13),
SUBSTRING(NOM,1,30) ,
SUBSTRING(COD_LBR_1,1,13),
''CLI''
FROM OPENQUERY'
SET @INTEG_PLC = 'SELECT
COD_CLT,
NOM,
COD_LBR_1
FROM CLIENTS'
SET @sSQL = @sSQL_PLC +
'(INTEGRALE_' + @SOCANA + ',
''' + @INTEG_PLC + ''')'
EXECUTE(@sSQL)
PRINT @sSQL
PRINT '# IMPORT CLI OK'
SET @sSQL_PLC = @sINSERTSQL +
' SELECT' +
'''' + @SOCANA + ''',
SUBSTRING(COD_FOU,1,13),
SUBSTRING(NOM,1,30) ,
SUBSTRING(COD_LBR_1,1,13),
''FOU''
FROM OPENQUERY'
SET @INTEG_PLC = 'SELECT
COD_FOU,
NOM,
COD_LBR_1
FROM FOURNISSEURS'
SET @sSQL = @sSQL_PLC +
'(INTEGRALE_' + @SOCANA + ',
''' + @INTEG_PLC + ''')'
EXECUTE(@sSQL)
PRINT @sSQL
PRINT '# IMPORT FOU OK'
-- REQUETE DE BASE TRANSFORMEE EN TABLE : GAIN DE TEMPSDROPTABLE TMP__BASE_INTRA_GROUPES
CREATETABLE TMP__BASE_INTRA_GROUPES
(
SIT_ANALYTIQUE char(3),
FIL_Code_filiale nchar(13),
FIL_Libelle char(30),
CFP_Type_de_compte char(3),
CPT_Collectif char(4),
CPT_Compte char(13),
CPT_LIBELLE char(30),
ECR_DATE datetime,
ECR_PIECE char(13),
ECR_DEBIT money,
ECR_CREDIT money,
ECR_LIBELLE char(30),
CTRL_ECR_DATE_YEAR int,
CTRL_ECR_DATE_MONTH int,
CPT_CONTREPARTIE_GROUPE char(3),
CPT_CONTREPARTIE char(13),
ECR_JOURNAL char(10),
ECR_NUM_LOT char(10))INSERTINTO TMP__BASE_INTRA_GROUPES(SIT_ANALYTIQUE, FIL_Code_filiale, FIL_Libelle, CFP_Type_de_compte, CPT_Collectif, CPT_Compte,
CPT_LIBELLE, ECR_DATE, ECR_PIECE, ECR_DEBIT, ECR_CREDIT, ECR_LIBELLE, CTRL_ECR_DATE_YEAR, CTRL_ECR_DATE_MONTH,
CPT_CONTREPARTIE_GROUPE, CPT_CONTREPARTIE, ECR_JOURNAL, ECR_NUM_LOT)
SELECT SIT_ANALYTIQUE, FIL_Code_filiale, FIL_Libelle, CFP_Type_de_compte, CPT_Collectif, CPT_Compte,
CPT_LIBELLE, ECR_DATE, ECR_PIECE, ECR_DEBIT, ECR_CREDIT, ECR_LIBELLE, CTRL_ECR_DATE_YEAR, CTRL_ECR_DATE_MONTH,
CPT_CONTREPARTIE_GROUPE, CPT_CONTREPARTIE, ECR_JOURNAL, ECR_NUM_LOT FROM VUE___BASE_INTRA_GROUPES
--COMMIT TRAN
--ALTER INDEX [IX_TB_ECRITURES] ON [dbo].[TB_ECRITURES] REORGANIZE WITH ( LOB_COMPACTION = ON )--ALTER INDEX [IX_TB_COMPTES] ON [dbo].[TB_COMPTES] REORGANIZE WITH ( LOB_COMPACTION = ON )
CHECKPOINT
BACKUP TRANSACTION CHIMCOMPTA WITH NO_LOG
DBCC SHRINKFILE(N'CHIMCOMPTA_log',0)
--END TRY--BEGIN CATCHSELECT
ERROR_NUMBER()AS ErrorNumber,
ERROR_SEVERITY()AS ErrorSeverity,
ERROR_STATE()AS ErrorState,
ERROR_PROCEDURE()AS ErrorProcedure,
ERROR_LINE()AS ErrorLine,
ERROR_MESSAGE()AS ErrorMessage;
--ROLLBACK TRAN--END CATCH
5. COMPORTEMENT :La SP fonctionne plutôt bien... sauf que (ben oui, il fallait bien un sauf que!). Il lui arrive de bloquer (a priori) sans aucune raison.
Dans le moniteur d'activité (refresh 5 secondes) j'observe ceci:
. IIS appelle l'instruction appellant la SP, quand tout va bien, je vois sur la ligne du processus un
temps d'attente compris entre 15 et 100, puis un appel à l'ODBC est fait pour une commande INSERT, et ce pour chacune des opérations prévues dans ma SP.
. Quand ça va bloquer, je ne vois nulle part mention faite aux ODBC mais un temps d'attente du processus qui grimpe, grimpe et jamais ne se débloque.
. Quand c'est bloqué, rien n'indique que le processus est bloqué par un autre ou en attente de quoi que ce soit de particulier.
. un KILL du processus qui part en attente n'a aucun effet sur lui, la seule solution que j'ai pu trouver est de redémarrer les services SQL.
6. TESTS EFFECTUES:. Tous les ODBC ont été testés les uns après les autres
. Les serveurs liés ont été créés par scripts, testés, OK
. En redémarrant les services SQL la situation peut être débloquée (pas toujours mais la plupart du temps)
. Les échecs arrivent la plupart du temps (pas systématique) avant l'exécution de cette SP pour 2 FILIALES données.
. Ce problème étais plus fréquent lorsque les indexes de mes tables SQL étaient activés (?).
. BEGIN TRANS / COMMIT / ROLLBACK n'ont aucun effet (mais je ne maîtrise par forcément).
7. SITUATION ACTUELLE:JE SUIS A BOUT DE NERFS!... J'aurais accepté que ça plante à chque fois, je me serais dit que j'avais fait une erreur. MAis le fait que ça puisse fonctionner et puis, plus me gonfle!!!!
Ah oui, j'allais oublier:Je récupère des caractères bizarres (des carrés), leur code ASCII me retourne 0. Ils n'ont aucune valeur mais lorsque sans traitement je veux afficher le résulat d'un recordset dans une pages ASP ou même NOTEPAD, l'affichage est stoppé au premier caractère en question rencontré.

--- AU SECOURS ---
De quelles autres informations avez-vous besoin pour vous forger une opinion sur ce sujet?
Bien amicalement,
David