Pourquoi il n'y a pas de vérification sémantique pour l'instruction ddl à l'intérieur s'il existe dans mssql?

Pourquoi cela (ddl) fonctionne sans erreur de compilation?

IF EXISTS(SELECT * FROM sys.columns WHERE OBJECT_ID('[dbo].[TableDoesNotExits]') = object_id) BEGIN ALTER TABLE [dbo].[TableDoesNotExits] ADD RandomColumn INT --Works fine END 

Alors que ce (dml) ne le fait pas? Donne l'erreur de compilation comme mentionné dans le commentaire de la requête Works lorsqu'il est enveloppé dans une requête dynamic? (en utilisant sp_executesql)

 IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='TableExists' AND COLUMN_NAME = 'ColumnDoesNotExists') BEGIN UPDATE dbo.TableExists SET ColumnDoesNotExists = 1 --Invalid column name 'ColumnDoesNotExists' WHERE 1 = 1 END 

Dans votre premier exemple, vous faites reference à une table inexistante.

Dans votre deuxième exemple, vous faites reference à une colonne inexistante dans une table existante.

Ces deux cas sont différents dans la façon dont SQL Server effectue la compilation.

Vous pouvez en savoir plus à ce sujet dans ce lien sur "Résolution de noms différés":

https://technet.microsoft.com/en-us/library/ms190686(v=sql.105).aspx

Je cite ici le paragraphe le plus pertinent:

La résolution de nom différée ne peut être utilisée que lorsque vous referencez des objects de table inexistants. Tous les autres objects doivent exister au moment où la procédure stockée est créée. Par exemple, lorsque vous referencez une table existante dans une procédure stockée, vous ne pouvez pas listr les colonnes inexistantes pour cette table.