2009-03-05 5 views
4

Je me sens comme un dork juste pour demander cela, mais je ne reçois aucune aide de Google, et j'ai parcouru tous les résultats de SO sur une simple recherche de SMO et je ne l'ai pas vu non plus .SQL SMO n'énumérant pas les tables

La version courte est que je commence à jouer avec T4. Je suis en expansion sur Oleg Sych's initial tutorial pour fournir une énumération sur toutes les tables pour créer un proc (delete IMHO plutôt stupide). Ceci est juste une expérience, donc son inutilité absolue ne me dérange pas. :)

Mon extension au tutoriel Oleg ressemble à ceci:

<#@ template language="C#" hostspecific="true" #> 
<#@ output extension="SQL" #> 
<#@ assembly name="Microsoft.SqlServer.ConnectionInfo" #> 
<#@ assembly name="Microsoft.SqlServer.Smo" #> 
<#@ import namespace="Microsoft.SqlServer.Management.Smo" #> 
<#@ include file="T4Toolbox.tt" #> 
<# 
    // Config variables 
    string serverName = "dbserver\\dbinstance"; 
    string dbName = "dbname"; 
#> 
USE <#= dbName #> 
<# 
    // Iterate over tables and generate procs 
    Server server = new Server(serverName); 
    Database database = new Database(server, dbName); 

    WriteLine("/* Number of tables: " + database.Tables.Count.ToString() + " */"); 

    foreach (Table table in database.Tables) 
    { 
     table.Refresh(); 
#> 
CREATE PROCEDURE <#= table.Name #>_Delete 
<# 
     PushIndent(" "); 
     foreach (Column column in table.Columns) 
     { 
      if (column.InPrimaryKey) 
       WriteLine("@" + column.Name + " " + column.DataType.Name); 
     } 
     PopIndent(); 
#> 
AS 
    DELETE FROM 
     <#= table.Name #> 
    WHERE 
<# 
     PushIndent("  "); 
     foreach (Column column in table.Columns) 
     { 
      if (column.InPrimaryKey) 
       WriteLine(column.Name + " = @" + column.Name); 
     } 
     PopIndent(); 
     WriteLine("GO"); 
    } 
#> 

Le problème est qu'il n'y a pas de tables sont renvoyés de la collection Tables. Ceci est validé par le compte SQL de table que je génère, qui génère 0.

Comme écrit, le code ci-dessus génère les éléments suivants:

USE dbname 
/* Number of tables: 0 */ 

Cependant, si je retire la boucle et la fourniture manuellement un nom de table valide qui existe dans cette base de données, il génère le (nouveau stupide) proc - Pour cette table.

Les tables sont séparées en un schéma, cela aurait-il une importance? En outre, cela va à l'encontre d'une instance SQL2005 - cela pourrait-il causer des problèmes? Enfin, je constate également que je ne peux pas énumérer des synonymes via la collection de synonymes. (Je pensais que je serais intelligent et que j'irais dans cette direction car les tables sont dans un schéma, mais j'ai des synonymes définis.) Mais pas de dés.)

Encore une fois, pour répéter, le code ci-dessus n'est naturellement pas une production, ni même la production digne. J'essaie juste d'apprendre à la fois le T4 et le SMO, et j'ai frappé un barrage routier en essayant de faire quelque chose que je pensais être ridiculement simple. :)

Répondre

8

SMO ne récupère pas automatiquement les métadonnées si vous créez simplement une nouvelle instance de la classe Database. Récupérer des métadonnées peut prendre un certain temps, surtout dans un environnement froid. Appelez database.Refresh() avant la boucle.

+0

Merci pour le conseil! Je suis certain que cela fonctionnera, mais je serai sûr et mettre à jour (et accepter ceci) si ce n'est pas le cas! –

+0

Vous rock. Absolument travaillé comme un charme. Merci encore! –

Questions connexes