增量ETL插入阶段INSERT关键字附近语法错误排查求助
增量ETL插入SQL脚本语法错误排查(Msg 156)
执行增量ETL插入操作时,SQL脚本触发如下错误:
Msg 156, Level 15, State 1, Procedure vue_FaitProduction, Line 38
[Batch Start Line 331] 'INSERT' 关键字附近语法不正确。
原脚本如下:
USE UsineFlex_DW GO DROP VIEW IF EXISTS vue_FaitProduction GO CREATE VIEW vue_FaitProduction AS SELECT P.NoProduit, U.NoUsine, LP.DateProduction, M.NoMachine, LP.Quantite, LP.UnitesEnergieConsommees, COUNT(EE.NoEntretienEffectue) AS NombreEntretiensEffectues, SUM(DATEDIFF(HOUR, EE.DHDebut, EE.DHFinReelle) * E.SalaireHoraire) AS CoutEntretiensEffectues FROM UsineFlexInc.dbo.ff_EntretienEffectue EE JOIN UsineFlexInc.dbo.ff_Machine M ON M.NoMachine = EE.NoMachine JOIN UsineFlexInc.dbo.ff_Usine U ON U.NoUsine = M.NoUsine JOIN UsineFlexInc.dbo.ff_LotProduction LP ON LP.NoMachine = M.NoMachine JOIN UsineFlexInc.dbo.ff_Produit P ON P.NoProduit = LP.NoProduit JOIN UsineFlexInc.dbo.ff_Employe E ON E.NoEmploye = EE.NoEmploye WHERE LP.DateModification > ( SELECT DateModification FROM UsineFlex_ETLConfig WHERE nomTable = 'FAIT_PRODUCTION' ) GROUP BY P.NoProduit, U.NoUsine, LP.DateProduction, M.NoMachine, LP.Quantite, LP.UnitesEnergieConsommees; -- Charger les données dans la table de fait à partir de la vue INSERT INTO FAIT_PRODUCTION (RefProduit, RefNoUsine, RefDateProduction, NoMachine, Quantite, UnitesEnergieConsommees, NombreEntretiensEffectues, CoutEntretiensEffectues) SELECT P.RefProduit, U.RefNoUsine, D.RefDate, FP.NoMachine, FP.Quantite, FP.UnitesEnergieConsommees, FP.NombreEntretiensEffectues, FP.CoutEntretiensEffectues FROM vue_FaitProduction FP INNER JOIN DIM_PRODUIT P ON(P.NoProduit = FP.NoProduit) AND P.Statut = 'Courant' INNER JOIN DIM_USINE U ON (U.NoUsine = FP.NoUsine) INNER JOIN DIM_DATE D ON D.RefDate = FP.DateProduction UPDATE UsineFlex_ETLConfig SET DateModification = getdate() WHERE nomTable = 'FAIT_PRODUCTION' GO
问题原因
SQL Server要求CREATE VIEW语句必须作为独立批处理执行。原脚本中,视图定义结束后直接编写INSERT和UPDATE语句,未用GO分隔批处理,导致SQL Server将这些语句误判为视图定义的一部分。而视图定义仅允许包含SELECT语句,因此触发语法错误。
修复后的脚本
在视图创建完成的分号后添加GO,将视图定义与后续操作拆分为独立批处理:
USE UsineFlex_DW GO DROP VIEW IF EXISTS vue_FaitProduction GO CREATE VIEW vue_FaitProduction AS SELECT P.NoProduit, U.NoUsine, LP.DateProduction, M.NoMachine, LP.Quantite, LP.UnitesEnergieConsommees, COUNT(EE.NoEntretienEffectue) AS NombreEntretiensEffectues, SUM(DATEDIFF(HOUR, EE.DHDebut, EE.DHFinReelle) * E.SalaireHoraire) AS CoutEntretiensEffectues FROM UsineFlexInc.dbo.ff_EntretienEffectue EE JOIN UsineFlexInc.dbo.ff_Machine M ON M.NoMachine = EE.NoMachine JOIN UsineFlexInc.dbo.ff_Usine U ON U.NoUsine = M.NoUsine JOIN UsineFlexInc.dbo.ff_LotProduction LP ON LP.NoMachine = M.NoMachine JOIN UsineFlexInc.dbo.ff_Produit P ON P.NoProduit = LP.NoProduit JOIN UsineFlexInc.dbo.ff_Employe E ON E.NoEmploye = EE.NoEmploye WHERE LP.DateModification > ( SELECT DateModification FROM UsineFlex_ETLConfig WHERE nomTable = 'FAIT_PRODUCTION' ) GROUP BY P.NoProduit, U.NoUsine, LP.DateProduction, M.NoMachine, LP.Quantite, LP.UnitesEnergieConsommees; -- 新增GO分隔批处理 GO -- Charger les données dans la table de fait à partir de la vue INSERT INTO FAIT_PRODUCTION (RefProduit, RefNoUsine, RefDateProduction, NoMachine, Quantite, UnitesEnergieConsommees, NombreEntretiensEffectues, CoutEntretiensEffectues) SELECT P.RefProduit, U.RefNoUsine, D.RefDate, FP.NoMachine, FP.Quantite, FP.UnitesEnergieConsommees, FP.NombreEntretiensEffectues, FP.CoutEntretiensEffectues FROM vue_FaitProduction FP INNER JOIN DIM_PRODUIT P ON(P.NoProduit = FP.NoProduit) AND P.Statut = 'Courant' INNER JOIN DIM_USINE U ON (U.NoUsine = FP.NoUsine) INNER JOIN DIM_DATE D ON D.RefDate = FP.DateProduction UPDATE UsineFlex_ETLConfig SET DateModification = getdate() WHERE nomTable = 'FAIT_PRODUCTION' GO
修复说明
GO关键字会通知SQL Server结束当前批处理并启动新批处理,确保视图定义被单独执行,后续的INSERT和UPDATE操作作为独立语句块被正确解析,消除语法错误。
内容的提问来源于stack exchange,提问作者Louis Charles Campagna
相关产品推荐
相关产品推荐

