{"id":1343,"date":"2010-08-03T15:45:24","date_gmt":"2010-08-03T14:45:24","guid":{"rendered":"http:\/\/blog.capdata.fr\/?p=1343"},"modified":"2022-11-21T17:06:21","modified_gmt":"2022-11-21T16:06:21","slug":"scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql","status":"publish","type":"post","link":"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/","title":{"rendered":"Scripting et SMO (suite): scripter les objets directement en T-SQL"},"content":{"rendered":"<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1343&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1343&#038;title=Scripting%20et%20SMO%20%28suite%29%3A%20scripter%20les%20objets%20directement%20en%20T-SQL\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=Scripting%20et%20SMO%20%28suite%29%3A%20scripter%20les%20objets%20directement%20en%20T-SQL&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1343\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a><p>Suite de l&#8217;article <a href=\"https:\/\/blog.capdata.fr\/index.php\/generer-le-ddl-complet-dune-base-en-csmo\/\">pr\u00e9c\u00e9dent<\/a>, o\u00f9 il \u00e9tait question de g\u00e9n\u00e9rer le DDL d&#8217;une base avec C# et SMO. Si on pousse l&#8217;id\u00e9e un peu plus loin, il serait s\u00e9duisant de pouvoir le faire directement dans une proc\u00e9dure stock\u00e9e, en s&#8217;interfa\u00e7ant avec SMO et sa m\u00e9thode Script(). La premi\u00e8re solution qui vient \u00e0 l&#8217;esprit, c&#8217;est \u00e9videmment SQLCLR.<\/p>\n<h2>SQLCLR vs COM Automation:<\/h2>\n<p>Seulement voil\u00e0, on s&#8217;y casse un peu les dents car comme le dit <a href=\"https:\/\/sqlskills.com\/blogs\/bobb\/post\/Two-things-you-cant-do-in-SQLCLR.aspx\">Bob Beauchemin<\/a>, SMO n&#8217;est pas support\u00e9 dans SQLCLR. Donc \u00e0 priori, adieu la m\u00e9thode Script(), et retour au clic-droit &#8230;<\/p>\n<p>Cet article propose une alternative qui utilise\u00a0 <strong>COM Automation<\/strong> (ou OLE Automation). C&#8217;est une fonctionnalit\u00e9 qui permet de charger un composant COM et d&#8217;utiliser ses m\u00e9thodes gr\u00e2ce \u00e0 des proc\u00e9dures stock\u00e9es \u00e9tendues sp_OA&#8230; C&#8217;est un peu l&#8217;anc\u00eatre de SQLCLR, mais avec moins de restrictions, donc plus de risques \u00e0 l&#8217;utilisation, c&#8217;est la raison pour laquelle cette technique est pas mal d\u00e9cri\u00e9e.<\/p>\n<p>D&#8217;ailleurs, en th\u00e9orie <strong>utiliser du SMO avec OLE Automation n&#8217;est pas support\u00e9 par SQL Server<\/strong>, pour des raisons de s\u00e9curit\u00e9 du code notamment, parce que par d\u00e9faut la DLL externe que l&#8217;on souhaite utiliser est charg\u00e9e dans le process address space du moteur, ce qui augmente le risque d&#8217;\u00e9craser de la m\u00e9moire li\u00e9e \u00e0 SQL Server et de crasher le processus tout entier ou de provoquer des fuites m\u00e9moire. Il existe tout un tas de recommandations contre l&#8217;usage de COM Automation avec SQL Server, et\u00a0 beaucoup de cas ont \u00e9t\u00e9 ouverts au support \u00e0 cause de \u00e7a. Il faut \u00e0 chaque fois que c&#8217;est possible lui pr\u00e9f\u00e9rer l&#8217;utilisation de SQLCLR. Sauf que dans notre cas, SMO n&#8217;\u00e9tant\u00a0 pas utilisable dans du SQLCLR, il ne reste que peu d&#8217;options.<\/p>\n<p>Une technique acceptable pour utiliser COM Automation sans mettre en p\u00e9ril l&#8217;instance est de charger le COM dans un processus s\u00e9par\u00e9 et d\u00e9di\u00e9, pour que tout probl\u00e8me de pointeur NULL ou de\u00a0 garbage collection dans le COM n&#8217;affecte pas SQL Server. Par exemple dans un web service accessible par Service Broker comme le propose <a href=\"https:\/\/smointsql.codeplex.com\/\">Simon Sabin<\/a>, ou dans un serveur COM+ comme nous allons le voir ici. Donc en r\u00e9sum\u00e9:<\/p>\n<p style=\"text-align: center;\"><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/Sans-COM_usage5.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1410 aligncenter\" title=\"Sans COM_usage\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/Sans-COM_usage5.jpg\" alt=\"\" width=\"681\" height=\"259\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/Sans-COM_usage5.jpg 681w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/Sans-COM_usage5-300x114.jpg 300w\" sizes=\"auto, (max-width: 681px) 100vw, 681px\" \/><\/a><\/p>\n<h2>Ecrire le COM object:<\/h2>\n<p>COM est un truc \u00e9norme et je ne peux pas en parler dans un article. Il faudrait un bon millier de pages pour d\u00e9crire ce que c&#8217;est dans les d\u00e9tails et ce que \u00e7a fait, mais disons que l&#8217;id\u00e9e derri\u00e8re COM est qu&#8217;un objet puisse publier ses classes et ses m\u00e9thodes pour permettre \u00e0 des applications tierces de pouvoir les utiliser sans pour autant divulguer son code source. Les objets COM existent le plus souvent sous la forme de librairies dynamiques (DLL). Le principe est utilis\u00e9 massivement dans \u00e0 peu pr\u00e8s toutes les applications Windows MFC ou Console, y compris SQL Server.<\/p>\n<p><strong>Pour pouvoir \u00eatre r\u00e9utilis\u00e9, un objet COM doit poss\u00e9der les caract\u00e9ristiques suivantes:<\/strong><br \/>\n&#8211; Ses classes doivent \u00eatre publiques et impl\u00e9menter une interface publique.<br \/>\n&#8211; Chaque classe doit poss\u00e9der un constructeur par d\u00e9faut (vide).<br \/>\n&#8211; La DLL doit \u00eatre sign\u00e9e.<br \/>\n&#8211; La DLL doit \u00eatre enregistr\u00e9e sur la machine sur laquelle on va l&#8217;utiliser.<\/p>\n<p>Par exemple pour scripter juste une table:<\/p>\n<pre><span style=\"color: #0000ff;\">using System;\r\nusing System.Collections.Generic;\r\nusing System.Collections.Specialized;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing Microsoft.SqlServer.Management.Smo;\r\nusing Microsoft.SqlServer.Management.Common;\r\n\r\nnamespace getDDL\r\n{\r\n     public interface IgetDDL    <span style=\"color: #008000;\">\/\/ &lt;- 1<\/span>\r\n     {\r\n         string ddlThis(string _srvname, string _dbname, int _objid);\r\n     }\r\n     public class cgetDDL : IgetDDL    <span style=\"color: #008000;\"> \/\/ &lt;- 2<\/span>\r\n     {\r\n         string ddlstr;\r\n\r\n         public cgetDDL() { }    <span style=\"color: #008000;\"> \/\/ &lt;- 3<\/span>\r\n\r\n         public string ddlThis(string _srvname, string _dbname, int _objid)     <span style=\"color: #008000;\">\/\/ &lt;- 4<\/span>\r\n         {\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n             Server Srv = new Server(_srvname);\r\n             Database Db = new Database();\r\n             Db = Srv.Databases[_dbname];\r\n             StringCollection _tablescr = Db.Tables.ItemById(_objid).Script();\r\n\r\n             foreach (string _line in _tablescr)\r\n<span style=\"color: #0000ff;\">                 ddlstr += _line;\r\n<\/span><\/span><span style=\"color: #0000ff;\">             ddlstr += \"GO\"+'\\n';\r\n\r\n             IndexCollection _indexes = _t.Indexes;\r\n             foreach (Index _i in _indexes)\r\n             {\r\n                 StringCollection _iscr = _i.Script();\r\n                 foreach (string _line in _iscr)\r\n                     ddlstr += _line + '\\n';\r\n             }\r\n             if (_indexes.Count != 0)\r\n                 ddlstr += \"GO\" + '\\n';\r\n\r\n             CheckCollection _checks = _t.Checks;\r\n             foreach (Check _c in _checks)\r\n             {\r\n                 StringCollection _cscr = _c.Script();\r\n                 foreach (string _line in _cscr)\r\n                     ddlstr += _line + '\\n';\r\n             }\r\n             if (_checks.Count != 0)\r\n                 ddlstr += \"GO\" + '\\n';\r\n\r\n             TriggerCollection _triggers = _t.Triggers;\r\n             foreach (Trigger _trg in _triggers)\r\n             {\r\n                 StringCollection _trgscr = _trg.Script();\r\n                 foreach (string _line in _trgscr)\r\n                     ddlstr += _line + '\\n';\r\n             }\r\n             if (_triggers.Count != 0)\r\n                 ddlstr += \"GO\" + '\\n';\r\n\r\n             foreach (Column _col in _t.Columns)\r\n             {\r\n                 if (_col.DefaultConstraint != null)\r\n                 {\r\n                     StringCollection _def = _col.DefaultConstraint.Script();\r\n                     foreach (string _line in _def)\r\n                         ddlstr += _line + '\\n';\r\n                     ddlstr += \"GO\" + '\\n';\r\n                 }\r\n            }<\/span>\r\n<span style=\"color: #0000ff;\">\r\n             return ddlstr;\r\n         }\r\n     }\r\n}<\/span><\/pre>\n<p><strong>&#8211;&gt; <\/strong><strong>1:<\/strong> D\u00e9claration de l&#8217;interface publique, qui va publier aux applications externes l&#8217;unique m\u00e9thode de la classe CgetDDL :: ddlThis()<br \/>\n<strong>&#8211;&gt;<\/strong> <strong>2:<\/strong> D\u00e9claration de la classe publique qui impl\u00e9mente l&#8217;interface.<br \/>\n<strong>&#8211;&gt; 3: <\/strong>D\u00e9claration de son constructeur par d\u00e9faut.<br \/>\n<strong>&#8211;&gt;<\/strong> <strong>4: <\/strong>D\u00e9claration de la m\u00e9thode, qui prend en arguments le nom de l&#8217;instance, le nom de la base et l&#8217;object_id de la table \u00e0 scripter. Pour le reste, cf l&#8217;<a href=\"https:\/\/blog.capdata.fr\/index.php\/generer-le-ddl-complet-dune-base-en-csmo\/\">article pr\u00e9c\u00e9dent<\/a>.<\/p>\n<p>Il faudra \u00e9galement modifier la propri\u00e9t\u00e9 <strong>ComVisible <\/strong>de l&#8217;assembly pour permettre d&#8217;y acc\u00e9der depuis l&#8217;ext\u00e9rieur. Dans assembly.cs:<\/p>\n<pre><span style=\"color: #0000ff;\">[assembly: ComVisible(<span style=\"color: #008000;\">true<\/span>)]<\/span><\/pre>\n<p>Enfin, il faut signer la DLL avec un nom fort que l&#8217;on pourra g\u00e9n\u00e9rer avec VS:<\/p>\n<p><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/sign_assembly.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1421\" title=\"sign_assembly\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/sign_assembly.jpg\" alt=\"\" width=\"770\" height=\"404\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/sign_assembly.jpg 770w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/sign_assembly-300x157.jpg 300w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/sign_assembly-768x403.jpg 768w\" sizes=\"auto, (max-width: 770px) 100vw, 770px\" \/><\/a><\/p>\n<h2>Chargement du COM dans un serveur COM+:<\/h2>\n<p>Une fois la DLL compil\u00e9e, il va falloir l&#8217;enregistrer sur la machine et g\u00e9n\u00e9rer un fichier Type Library (*.tlb) que l&#8217;on va utiliser ensuite dans le serveur COM+. Pour enregistrer une dll et g\u00e9n\u00e9rer le tlb, on utilise l&#8217;utilitaire <strong>regasm <\/strong>qui est fournit avec tous les frameworks .NET (et qui doit se trouver qq part sous C:\\Windows\\Microsoft .NET\\Framework\\&#8230;):<\/p>\n<pre><span style=\"color: #0000ff;\">DOS &gt;regasm \/codebase getDDL.dll \/tlb:getDDL.tlb\r\n<em>Microsoft (R) .NET Framework Assembly Registration Utility 2.0.50727.3053\r\nCopyright (C) Microsoft Corporation 1998-2004. Tous droits r\u00e9serv\u00e9s.<\/em>\r\n\r\nInscription des types r\u00e9ussie\r\nL'assembly a \u00e9t\u00e9 export\u00e9 vers 'C:\\DBA\\DEV\\C#\\getDDL\\bin\\Debug\\getDDL.tlb' et la biblioth\u00e8que de types a \u00e9t\u00e9 inscrite avec succ\u00e8s<\/span><\/pre>\n<p>A partir de l\u00e0, on va cr\u00e9er un nouveau serveur COM+ en utilisant le service de composants <em><strong>comexp.msc<\/strong><\/em>: dans <em>Services des composants -&gt; Ordinateurs -&gt; Poste de travail -&gt; Applications COM+<\/em>, on cr\u00e9\u00e9 une nouvelle application serveur vide, d\u00e9marr\u00e9e sous un compte windows qui serait reconnu comme sysadmin sur l&#8217;instance (par exemple l&#8217;admin local, ou tout autre compte windows sysadmin). On d\u00e9pose ensuite le fichier tlb dans les composants de la nouvelle application COM+, et on v\u00e9rifie si la m\u00e9thode est bien expos\u00e9e:<\/p>\n<p style=\"text-align: center;\"><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/COMP.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1435 aligncenter\" title=\"COMP\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/COMP.jpg\" alt=\"\" width=\"408\" height=\"305\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/COMP.jpg 408w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/COMP-300x224.jpg 300w\" sizes=\"auto, (max-width: 408px) 100vw, 408px\" \/><\/a><\/p>\n<p>Enfin on d\u00e9marre le serveur COM+, et on v\u00e9rifie qu&#8217;un nouveau processus h\u00f4te de dll (dllhost.exe) est bien d\u00e9marr\u00e9 avec le bon compte. On va pouvoir s&#8217;int\u00e9resser \u00e0 la partie T-SQL.<\/p>\n<h2>Ecriture de la proc\u00e9dure stock\u00e9e:<\/h2>\n<p>Avant toute chose, pour pouvoir autoriser SQL Server \u00e0 utiliser Ole Automation, il faut l&#8217;activer dans les param\u00e8tres de configuration:<\/p>\n<pre><span style=\"color: #0000ff;\">sp_configure '<span style=\"color: #ff0000;\">Ole Automation Procedures<\/span>',1;\r\nGO\r\nreconfigure;\r\nGO<\/span><\/pre>\n<p>Ensuite, on cr\u00e9\u00e9 la proc\u00e9dure stock\u00e9e qui va charger le COM et utiliser la m\u00e9thode ddlThis():<\/p>\n<pre><span style=\"color: #0000ff;\">create procedure usp_getDDL (@tablename varchar(128))\r\nAS\r\nBEGIN\r\n     DECLARE @hr int, @obj int;\r\n     DECLARE @Source nvarchar(255), @Desc nvarchar(255);\r\n     DECLARE @DDLTEXT nvarchar(4000);\r\n     DECLARE @dbname sysname, @objid int, @srvname sysname;\r\n\r\n     select @srvname = @@servername\r\n     select @dbname= db_name()\r\n     select @objid = object_id(@tablename)\r\n     if (@objid is NULL)\r\n     BEGIN\r\n         print 'Table '+@tablename+' non trouvee dans la base courante'\r\n         RETURN\r\n     END\r\n\r\n     execute @hr = sp_OACreate '<span style=\"color: #ff0000;\">getDDL.cgetDDL<\/span>', @obj OUT,<span style=\"color: #ff0000;\"> 4         <span style=\"color: #008000;\"> --&gt; context = 4 =&gt; <\/span><\/span><\/span><span style=\"color: #008000;\">COM stock\u00e9 dans un dllhost.exe, pas dans sqlservr.exe<\/span><span style=\"color: #0000ff;\">\r\n     if (@hr &lt;&gt; 0)\r\n     BEGIN\r\n         EXEC sp_OAGetErrorInfo @obj,\r\n         @Source OUT,\r\n         @Desc OUT;\r\n         SELECT HR = convert(varbinary(4),@hr),\r\n         Source=@Source,\r\n         Description=@Desc;\r\n         RETURN\r\n     END\r\n\r\n     execute @hr = sp_OAMethod @obj, '<span style=\"color: #ff0000;\">ddlThis<\/span>', @DDLTEXT OUT, @srvname, @dbname, @objid\r\n     if (@hr &lt;&gt; 0)\r\n     BEGIN\r\n         EXEC sp_OAGetErrorInfo @obj,\r\n         @Source OUT,\r\n         @Desc OUT;\r\n         SELECT HR = convert(varbinary(4),@hr),\r\n         Source=@Source,\r\n         Description=@Desc;\r\n         RETURN\r\n     END\r\n\r\n     execute @hr = sp_OADestroy @obj\r\n\r\n     select @DDLTEXT as 'DDL'\r\nEND<\/span><\/pre>\n<p>La proc\u00e9dure r\u00e9cup\u00e8re le nom de la table, v\u00e9rifie si celle-ci existe dans la base courante, et charge le COM dans le dllhost.exe avec <strong>sp_OACreate<\/strong>. Le nom du COM object est celui d\u00e9clar\u00e9 dans le serveur COM+ . Un autre param\u00e8tre d&#8217;extr\u00eame importance est le dernier pass\u00e9 \u00e0 sp_OACreate\u00a0 (4). <strong>Il s&#8217;agit du contexte de chargement du COM, <\/strong>dans ce cas 4 indique \u00e0 SQL Server que le composant sera charg\u00e9 en dehors de son process address space et ne peut avoir acc\u00e8s aux ressources m\u00e9moire dans sqlservr.exe (cf <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms189763.aspx\">MSDN<\/a>). C&#8217;est notre garde-fou et c&#8217;est indispensable, car par d\u00e9faut, la ddl aurait \u00e9t\u00e9 charg\u00e9e dans sqlservr.exe et aurait p\u00fb causer des d\u00e9g\u00e2ts, il est donc tr\u00e8s important de proc\u00e9der de cette mani\u00e8re.<\/p>\n<p>Ensuite la proc\u00e9dure appelle <strong>sp_OAMethod<\/strong> pour invoquer la m\u00e9thode expos\u00e9e par l&#8217;interface du COM, et r\u00e9cup\u00e8re le DDL dans un nvarchar(4000). A la fin du processus, la r\u00e9f\u00e9rence vers l&#8217;objet est d\u00e9truite avec <strong>sp_OADestroy<\/strong>.<\/p>\n<p>A l&#8217;appel de la proc\u00e9dure:<\/p>\n<pre><span style=\"color: #0000ff;\">DOS&gt;sqlcmd -E\r\n1&gt; use CAPDATA\r\n2&gt; go\r\nLe contexte de la base de donn\u00e9es a chang\u00e9\u00a0; il est maintenant 'CAPDATA'.\r\n1&gt; exec usp_getddl 'ANNONCE'\r\n2&gt; go\r\n\r\n<em>DDL\r\n------------------------------------------------------------------------------------------------------<\/em>\r\n\r\nSET ANSI_NULLS ON\r\nSET QUOTED_IDENTIFIER ON\r\nCREATE TABLE [dbo].[ANNONCE](\r\n [ID_ANNONCE] [int] NOT NULL,\r\n [ID_JOURNAL] [int] NOT NULL,\r\n [ID_PROPALOUER] [int] NOT NULL,\r\n [DATETIME_ANNONCE] [datetime] NOT NULL,\r\n [PRIX] [numeric](6, 2) NULL,\r\n [NB_PARUTION] [int] NULL\r\n) ON [PRIMARY]\r\n\r\nGO\r\nALTER TABLE [dbo].[ANNONCE] ADD\u00a0 CONSTRAINT [PK_ANNONCE] PRIMARY KEY CLUSTERED\r\n(\r\n [ID_ANNONCE] ASC\r\n)WITH (PAD_INDEX\u00a0 = OFF, STATISTICS_NORECOMPUTE\u00a0 = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF,\r\nONLINE = OFF, ALLOW_ROW_LOCKS\u00a0 = ON, ALLOW_PAGE_LOCKS\u00a0 = ON) ON [PRIMARY]\r\nGO<\/span><\/pre>\n<h2>Conclusion:<\/h2>\n<p>COM ou Ole Automation est une technique pour faire communiquer SQL Server avec des composants externes. Elle\u00a0 pr\u00e9sente des risques \u00e9lev\u00e9s de corruption m\u00e9moire lorsqu&#8217;on l&#8217;utilise avec les param\u00e8tres de contexte par d\u00e9faut, mais lorsqu&#8217;on manipule l&#8217;objet \u00e0 travers son propre conteneur, les risques sont limit\u00e9s.<\/p>\n<p>Dans la mesure o\u00f9 SMO n&#8217;est pas support\u00e9 avec SQLCLR, elle repr\u00e9sente une alternative int\u00e9ressante pour pouvoir interfacer SQL Server avec des fonctions qui ne sont pas disponibles ailleurs.<\/p>\n<p>A+. David B.<\/p>\n<p><script src=\"https:\/\/tcr.tynt.com\/javascripts\/Tracer.js?user=d4FlbGI04r35lZadbi-bpO\" type=\"text\/javascript\"><\/script><\/p>\n<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1343&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1343&#038;title=Scripting%20et%20SMO%20%28suite%29%3A%20scripter%20les%20objets%20directement%20en%20T-SQL\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=Scripting%20et%20SMO%20%28suite%29%3A%20scripter%20les%20objets%20directement%20en%20T-SQL&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1343\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a>","protected":false},"excerpt":{"rendered":"<p>Suite de l&#8217;article pr\u00e9c\u00e9dent, o\u00f9 il \u00e9tait question de g\u00e9n\u00e9rer le DDL d&#8217;une base avec C# et SMO. Si on pousse l&#8217;id\u00e9e un peu plus loin, il serait s\u00e9duisant de pouvoir le faire directement dans une proc\u00e9dure stock\u00e9e, en s&#8217;interfa\u00e7ant&hellip; <a href=\"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/\" class=\"more-link\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":7942,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[158,167,168,166,160,159],"class_list":["post-1343","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sqlserver","tag-c","tag-com","tag-ddl","tag-ole-automation","tag-script","tag-smo"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Scripting et SMO (suite): scripter les objets directement en T-SQL - Capdata TECH BLOG<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Scripting et SMO (suite): scripter les objets directement en T-SQL - Capdata TECH BLOG\" \/>\n<meta property=\"og:description\" content=\"Suite de l&#8217;article pr\u00e9c\u00e9dent, o\u00f9 il \u00e9tait question de g\u00e9n\u00e9rer le DDL d&#8217;une base avec C# et SMO. Si on pousse l&#8217;id\u00e9e un peu plus loin, il serait s\u00e9duisant de pouvoir le faire directement dans une proc\u00e9dure stock\u00e9e, en s&#8217;interfa\u00e7ant&hellip; Continuer la lecture &rarr;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/\" \/>\n<meta property=\"og:site_name\" content=\"Capdata TECH BLOG\" \/>\n<meta property=\"article:published_time\" content=\"2010-08-03T14:45:24+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-11-21T16:06:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/code2.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"852\" \/>\n\t<meta property=\"og:image:height\" content=\"480\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"David Baffaleuf\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"David Baffaleuf\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/\"},\"author\":{\"name\":\"David Baffaleuf\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/136297da9f61d6e4878abe0f48bc5fbf\"},\"headline\":\"Scripting et SMO (suite): scripter les objets directement en T-SQL\",\"datePublished\":\"2010-08-03T14:45:24+00:00\",\"dateModified\":\"2022-11-21T16:06:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/\"},\"wordCount\":1209,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"keywords\":[\"C#\",\"COM\",\"DDL\",\"ole automation\",\"SCRIPT\",\"SMO\"],\"articleSection\":[\"SQL Server\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/\",\"url\":\"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/\",\"name\":\"Scripting et SMO (suite): scripter les objets directement en T-SQL - Capdata TECH BLOG\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/#website\"},\"datePublished\":\"2010-08-03T14:45:24+00:00\",\"dateModified\":\"2022-11-21T16:06:21+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/blog.capdata.fr\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Scripting et SMO (suite): scripter les objets directement en T-SQL\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.capdata.fr\/#website\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"name\":\"Capdata TECH BLOG\",\"description\":\"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting\",\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.capdata.fr\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/blog.capdata.fr\/#organization\",\"name\":\"Capdata TECH BLOG\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"contentUrl\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"width\":800,\"height\":254,\"caption\":\"Capdata TECH BLOG\"},\"image\":{\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/136297da9f61d6e4878abe0f48bc5fbf\",\"name\":\"David Baffaleuf\",\"sameAs\":[\"http:\/\/www.capdata.fr\"],\"url\":\"https:\/\/blog.capdata.fr\/index.php\/author\/dbaffaleuf\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Scripting et SMO (suite): scripter les objets directement en T-SQL - Capdata TECH BLOG","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/","og_locale":"fr_FR","og_type":"article","og_title":"Scripting et SMO (suite): scripter les objets directement en T-SQL - Capdata TECH BLOG","og_description":"Suite de l&#8217;article pr\u00e9c\u00e9dent, o\u00f9 il \u00e9tait question de g\u00e9n\u00e9rer le DDL d&#8217;une base avec C# et SMO. Si on pousse l&#8217;id\u00e9e un peu plus loin, il serait s\u00e9duisant de pouvoir le faire directement dans une proc\u00e9dure stock\u00e9e, en s&#8217;interfa\u00e7ant&hellip; Continuer la lecture &rarr;","og_url":"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/","og_site_name":"Capdata TECH BLOG","article_published_time":"2010-08-03T14:45:24+00:00","article_modified_time":"2022-11-21T16:06:21+00:00","og_image":[{"width":852,"height":480,"url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2010\/08\/code2.jpg","type":"image\/jpeg"}],"author":"David Baffaleuf","twitter_card":"summary_large_image","twitter_misc":{"\u00c9crit par":"David Baffaleuf","Dur\u00e9e de lecture estim\u00e9e":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/#article","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/"},"author":{"name":"David Baffaleuf","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/136297da9f61d6e4878abe0f48bc5fbf"},"headline":"Scripting et SMO (suite): scripter les objets directement en T-SQL","datePublished":"2010-08-03T14:45:24+00:00","dateModified":"2022-11-21T16:06:21+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/"},"wordCount":1209,"commentCount":0,"publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"keywords":["C#","COM","DDL","ole automation","SCRIPT","SMO"],"articleSection":["SQL Server"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/","url":"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/","name":"Scripting et SMO (suite): scripter les objets directement en T-SQL - Capdata TECH BLOG","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/#website"},"datePublished":"2010-08-03T14:45:24+00:00","dateModified":"2022-11-21T16:06:21+00:00","breadcrumb":{"@id":"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.capdata.fr\/index.php\/scripting-et-smo-suite-scripter-les-objets-directement-en-t-sql\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/blog.capdata.fr\/"},{"@type":"ListItem","position":2,"name":"Scripting et SMO (suite): scripter les objets directement en T-SQL"}]},{"@type":"WebSite","@id":"https:\/\/blog.capdata.fr\/#website","url":"https:\/\/blog.capdata.fr\/","name":"Capdata TECH BLOG","description":"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting","publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.capdata.fr\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/blog.capdata.fr\/#organization","name":"Capdata TECH BLOG","url":"https:\/\/blog.capdata.fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/","url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","contentUrl":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","width":800,"height":254,"caption":"Capdata TECH BLOG"},"image":{"@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/"]},{"@type":"Person","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/136297da9f61d6e4878abe0f48bc5fbf","name":"David Baffaleuf","sameAs":["http:\/\/www.capdata.fr"],"url":"https:\/\/blog.capdata.fr\/index.php\/author\/dbaffaleuf\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/1343","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/comments?post=1343"}],"version-history":[{"count":163,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/1343\/revisions"}],"predecessor-version":[{"id":9531,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/1343\/revisions\/9531"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media\/7942"}],"wp:attachment":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media?parent=1343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/categories?post=1343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/tags?post=1343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}