Archiv der Kategorie '1'

Automatisches Erzeugen eines Datenbankdiagrams aus einer MSSQL-Datenbank mit Hilfe von YED

Mit dem Microsoft SQL Server Management Studio (Express) kann man seiner Datenbank unter dem Punkt „Database Diagrams“ eine grafische Darstellung der Datenbank hinzufügen.

Soweit so gut – nur sieht das dann meistens so aus:

ERMSQL

Also nicht gerade übersichtlich. Und das Ganze per Hand in eine schöne Form zu bringen ist sehr mühselig.

Aber es gibt ein schönes Freewareprogramm: YED. Damit kann man sehr schön Diagramme machen. Und vor allem: es kann die Elemente automatisch anordnen, so dass sie (einigermaßen) übersichtlich dargestellt werden. Aber leider kann es keine Datenbankstruktur auslesen…

Aber wozu ist man Programmierer….

Nachfolgendes C#.net Konsolen-Programm liest aus einer Datenbank die Tabellen aus, holt sich die Beziehungen (Relationships) der Tabellen untereinander und speichert es in Form einer *.gml Datei ab.

  1. class Program
  2.     {
  3.         /// <summary>
  4.         /// Datenstruktur für die Beziehungen (TabelleA nach TabelleB)
  5.         /// </summary>
  6.         public struct Relationship
  7.         {
  8.             public String tableA;
  9.             public String tableB;
  10.         }
  11.         static void Main(string[] args)
  12.         {
  13.  
  14.             try
  15.             {
  16.                 SqlConnection dbConnection = new SqlConnection
  17.                  (@"data source=xxxxx;Integrated Security=SSPI;initial catalog=xxxx;persist security info=false;packet size=4096");
  18.                 dbConnection.Open();
  19.                 List<String> tables = GetTableNames(dbConnection);
  20.                 List<Relationship> rels = GetRelationsships(dbConnection);
  21.                 SaveGml(TablesToGml(tables), RelationshipsToGml(rels));
  22.                 Console.WriteLine("Die Datei wurde erfolgreich erzeugt");
  23.                
  24.             }
  25.             catch (Exception e)
  26.             {
  27.                 Console.Write(e.Message);
  28.             }
  29.             Console.ReadLine();
  30.         }
  31.  
  32.         /// <summary>
  33.         /// Speichert die endgültige GML-Datei ab.
  34.         /// </summary>
  35.         /// <param name="tables"></param>
  36.         /// <param name="rels"></param>
  37.         private static void SaveGml(string tables, string rels)
  38.         {
  39.             File.WriteAllText("test.gml",
  40.                 @"Creator   ""yFiles""
  41. Version ""2.6""
  42. graph
  43. [
  44.     hierarchic  1
  45.     label   """"
  46.     directed    1" + tables + rels+"]");
  47.         }
  48.  
  49.         /// <summary>
  50.         /// Wandelt die Liste der Tabelle ins (stark vereinfachte) GML-Format um.
  51.         /// </summary>
  52.         /// <param name="tables"></param>
  53.         /// <returns></returns>
  54.         public static String TablesToGml(List<String> tables)
  55.         {
  56.             String gml = "";
  57.             foreach (string tab in tables)
  58.             {
  59.                gml = String.Concat(gml,Environment.NewLine,
  60.                     "node",Environment.NewLine,
  61.                     "[",Environment.NewLine,
  62.                     "id \""+tab+"\"",Environment.NewLine,
  63.                     "label  \""+tab+"\"",Environment.NewLine,
  64.                     "]");
  65.             }
  66.             return gml;
  67.         }
  68.  
  69.         /// <summary>
  70.         /// Wandelt die Liste der Beziehungen ins (stark vereinfachte) GML-Format um
  71.         /// </summary>
  72.         /// <param name="rels"></param>
  73.         /// <returns></returns>
  74.         public static String RelationshipsToGml(List<Relationship> rels)
  75.         {
  76.             String gml = "";
  77.             foreach (Relationship rel in rels)
  78.             {
  79.                 gml = String.Concat(gml,Environment.NewLine,
  80.                     "edge",Environment.NewLine,
  81.                     "[",Environment.NewLine,
  82.                     "   source \""+rel.tableA+"\"",Environment.NewLine,
  83.                     "   target \""+rel.tableB+"\"",Environment.NewLine,
  84.                     "]");
  85.             }
  86.             return gml;
  87.         }
  88.        
  89.         /// <summary>
  90.         /// Liest die Namen der Tabellen aus der Datenbank
  91.         /// </summary>
  92.         /// <param name="dbConnection"></param>
  93.         /// <returns></returns>
  94.         public static List<String> GetTableNames(SqlConnection dbConnection)
  95.         {
  96.             List<string> tables = new List<string>();
  97.             SqlCommand sqlCommand = dbConnection.CreateCommand();
  98.             sqlCommand.CommandText =
  99.                 @"Select Name from dbo.sysobjects WHERE xType = 'U' order by Name";
  100.             SqlDataReader sqlReader = sqlCommand.ExecuteReader();
  101.             while (sqlReader.Read())
  102.             {
  103.                 tables.Add(sqlReader["Name"].ToString());
  104.             }
  105.             sqlReader.Close();
  106.             return tables;
  107.         }
  108.  
  109.         /// <summary>
  110.         /// Liest die Relationsships aus der Datenbank aus
  111.         /// </summary>
  112.         /// <param name="dbConnection"></param>
  113.         /// <returns></returns>
  114.         public static List<Relationship> GetRelationsships(SqlConnection dbConnection)
  115.         {
  116.             List<Relationship> rel = new List<Relationship>();
  117.             SqlCommand sqlCommand = dbConnection.CreateCommand();
  118.             sqlCommand.CommandText =
  119.                 @"SELECT
  120. K_Table = FK.TABLE_NAME,
  121. FK_Column = CU.COLUMN_NAME,
  122. PK_Table = PK.TABLE_NAME,
  123. PK_Column = PT.COLUMN_NAME,
  124. Constraint_Name = C.CONSTRAINT_NAME
  125. FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
  126. INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
  127. INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
  128. INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
  129. INNER JOIN (
  130. SELECT i1.TABLE_NAME, i2.COLUMN_NAME
  131. FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
  132. INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
  133. WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
  134. ) PT ON PT.TABLE_NAME = PK.TABLE_NAME";
  135.             SqlDataReader sqlReader = sqlCommand.ExecuteReader();
  136.             while (sqlReader.Read())
  137.             {
  138.                 Relationship singleRel = new Relationship();
  139.                 singleRel.tableA = sqlReader["K_Table"].ToString();
  140.                 singleRel.tableB = sqlReader["PK_Table"].ToString();
  141.  
  142.                 //Gibt's mehrere gleiche Beziehungen wird nur EINE dargestellt.
  143.                 if (!rel.Contains(singleRel))
  144.                 {
  145.                     rel.Add(singleRel);
  146.                 }
  147.  
  148.             }
  149.             sqlReader.Close();
  150.             return rel;
  151.  
  152.         }
  153.     }

Die damit erzeugte Datei „test.gml“ kann man nun mit YED öffnen – und sieht dann so aus:

ERMYED_First

Alle „Kästchen“ sind hier hintereinander angeordnet, da ich mit obigem Programm nur ein vereinfachtes GML-Format angelegt habe. Das macht aber nichts, denn YED kann nun daraus ein übersichtliches Diagramm machen!

Man wählt dazu lediglich aus:

Layout – Orthogonal – Kompakt
YedMenue

Und siehe da: nun habe ich ein schönes Datenmodell, das ich nur noch ein bischen aufhübschen muß! Die Breite der Kästchen ändert man am besten gleich zuerst: alles markieren und per Maus breiter ziehen. Hintergrundfarbe festlegen, etwas rumspielen und fertig:

ERMYED

Einzige Voraussetzung ist, dass die Beziehungen zwischen den Tabellen auch in der Datenbank als Relationships angelegt sind.

Danke an
Bernhard für den Tipp mit YED
Pinal Dave für die Select-Anweisung

Tibet-Freunde leben gefährlich…

China ist allgegenwärtig – und dank des Internets mitten in unseren Wohnzimmern. Wie in einem schweizer BLOG zu lesen, startet China Hacker-Angriffe auf Webseiten und Rechner von Tibet-Sympathisanten.
Mehr dazu im RainbowNet Blog Schweiz

Dazu kann ich nur eines sagen:

Visual Studio 2008 – Installationsprobleme

Endlich ist es soweit! Die Visual Studio 2008 DVD ist angekommen.
Voller Vorfreude lege ich mit der Installation los, schließlich erwarten mich viele neue Features, die ich schon längst haben möchte. Doch die Freude währt kurz – der Installer bleibt beim Schritt „Microsoft Visual Studio 2008″ mit dem Prozeß „hxMeger_vsipcc_x86_de….“ hängen. Auch nach 30 Minuten tut sich nichts, im Taskmanager zeigt nur noch der Leerlaufprozess Aktivität… Was tun?

Im Internet findet man ähnliche Fehlerberichte – aber keine Lösung.

Visual Studio 2008

Also durchforste ich den Taskmanager und kille den einen oder anderen Prozess – ohne Wirkung. Der Installationsprozess „devenv.exe“, der eigentlich VS installieren sollte schläft. Kurzer Hand wird der Prozess gekillt – und siehe da: die Installation läuft weiter!

Doch nur, um dann beim Schritt „Crystal Reports Basic für Visual Studio 2008″ wieder hängen zu bleiben.

Wieder wird devenv.exe abgeschossen – er hat schon über 100 MB Speicher belegt.
Und wieder läuft die Installation weiter.

Doch devenv.exe gibt nicht auf – der Prozess erscheint sofort wieder neu. Und hängt beim „Crystal Reports Basic Language Pack“. Wieder abgeschossen.

Wieder läuft die Installation weiter – fast bis zum Schluß. Bei „MS SQL-Veröffentlichungsassisten“ tut sich wieder nichts. Nachdem der Fortschrittsbalken geraume Zeit bei 100% ist wird devenv.exe wieder mal abgeschossen.

Die Installation wurde – trotz der Abschüsse – als erfolgreich gemeldet.
Ob durch die wilde Schießerei später Probleme auftreten werden, wird sich zeigen. Zumindest läuft VS 2008 und auch meine Projekte lassen sich öffnen und laufen. Was will man mehr? (Außer vielleicht eine problemlose Installation…)

Keine abstehenden Post-it mehr!

Post-It ZettelWer nutzt sie nicht, die kleinen gelben Zettelchen?
Und hat es Euch auch schon geärgert, daß sie unten, am nicht klebenden Ende, immer abstehen? Nun – im Internet gibts wie so oft die Lösung! Dave Gray zeigt auf einem Video, wie man’s richtig macht damit’s auch mit den Post-It Zettelchen klappt….
Hier gehts zum Video

Advent, Advent – ein Büchlein brennt

Die Adventszeit bringt auch Entwickler auf gute Ideen: Auf der Homepage von entwickler-press.de gibt es einen Adventskalender. Nichts besonderes zu dieser Jahreszeit. Aber das Schöne an diesem Adventskalender: hinter jedem Türchen gibt es ein eBook zum download. Heute (und nur heute) z.B. ein Java-Buch.
Mal schauen, was es morgen gibt….

Pfui Papa, pfui Benedetto

Papst BenediktSchmeichelhaft war es ja schon, als wir „unseren“ Pabst bekamen. Noch dazu einer, der im selben Landkreis lebte wie ich. War mir Kardinal Ratzinger in manchen Dingen suspekt so war er mir als Pabst Benedetto doch wieder sympathischer.

Zumindest bist heute.

Heute hat er mich schon in aller früh geärgert als ich die Schlagzeile las: Pabst Benedikt wird sich mit dem Dalai Lama nicht treffen. Eine zuvor schon vereinbarte Audienz wurde wieder abgesagt, weil der Papst die Beziehungen zu China nicht gefährden will.

Ich war damals zutiefst von Angelika Merkel beeindruckt als sie gegen alle Proteste den Dalai Lama empfing. Daß aber jetzt ausgerechnet der Papst vor China kuscht, das hätte ich nie gedacht!

Wie lange wollen wir eigentlich noch vor der neuen Weltmacht China den Schwanz einziehen? Wer Geld hat darf Menschenrechte verletzen? Wer Geld hat darf Menschen töten, foltern, schänden und was weiß ich noch alles?

Pfui Benedikt - gerade Du als Oberhaupt einer Kirche hättest hier ein Zeichen setzen müssen. Wäre ich nicht schon längst aus Deiner Kirche ausgetreten – jetzt wäre es endgültig so weit….

Dalai Lama

Brainfarts ist tot – es lebe Medikula

Ich gestehe: ich las Brainfarts!
Mir gefiel der Blog und die Einblicke die er mir in den letzten Monaten in die Welt des Rettungsdienstes gab. Aber auch die anderen Themen wie Studium, Bergsteigen etc. sind (meistens) interessant für mich.

medikula.gifIn letzter Zeit hat Brainfarts jedoch etwas geschwächelt – er blogte wenig und seine Themen waren – in meinen Augen – oft etwas abstrus. Brainfarts sah das wohl genauso – und beendete seinen Blog. Jedoch nicht, ohne eine „Spur“ – sprich ein Rätsel – zu hinterlassen, das den Blogleser auf seinen neuen Blog führen soll.

Ist das der Versuch seine Blog-Leser zu selektieren? Nur die mit bestimmten IQ dürfen weiterlesen?
Wie auch immer – ich habe den Test bestanden — Wikipedia sei Dank!!!

Und so darf ich bei Medikula weiterlesen – seinem neuen Blog. Neues Studium – neuer Blog — ich bin schon gespannt auf Deine neuen Beiträge Joschua!!!


 

November 2009
M D M D F S S
« Jul    
 1
2345678
9101112131415
16171819202122
23242526272829
30  

Kategorien