diff --git a/DatabaseObjects/QueryBuilder.cs b/DatabaseObjects/QueryBuilder.cs index 56a40c7..0ac5f65 100644 --- a/DatabaseObjects/QueryBuilder.cs +++ b/DatabaseObjects/QueryBuilder.cs @@ -197,7 +197,7 @@ public static string GetDatabaseList() public static string GetTableListWithRowCounts() { return string.Format( - "SELECT DISTINCT{0}\tt.name \"Table\",{0}\tp.rows \"Rows\"{0}FROM {0}\tsys.tables t{0}INNER JOIN{0}\tsys.partitions p ON (t.object_id = p.object_id AND p.index_id < 2){0}WHERE{0}\tt.is_ms_shipped = 0{0}ORDER BY{0}\tt.name", + "SELECT DISTINCT{0}\ts.name \"Schema\",{0}\tt.name \"Table\",{0}\tt.object_id \"Id\",{0}\tp.rows \"Rows\"{0}FROM {0}\tsys.tables t{0}INNER JOIN{0}\tsys.schemas s ON (t.schema_id = s.schema_id){0}INNER JOIN{0}\tsys.partitions p ON (t.object_id = p.object_id AND p.index_id < 2){0}WHERE{0}\tt.is_ms_shipped = 0{0}", Environment.NewLine); } diff --git a/DatabaseObjects/TableDefinition.cs b/DatabaseObjects/TableDefinition.cs index 9a0d8ec..53fc26e 100644 --- a/DatabaseObjects/TableDefinition.cs +++ b/DatabaseObjects/TableDefinition.cs @@ -9,7 +9,7 @@ public class TableDefinition { private readonly List columns; - public TableDefinition(string name, ConnectionData connectionData) + public TableDefinition(string name, long id, ConnectionData connectionData) { Name = name; columns = new List(); @@ -31,14 +31,14 @@ public TableDefinition(string name, ConnectionData connectionData) if (hasExtendedPropertiesTable) cmd.CommandText = - $@"SELECT scol.name, stype.name, CASE stype.name WHEN 'decimal' THEN CAST(scol.xprec AS VARCHAR)+','+CAST(scol.xscale AS VARCHAR) ELSE CAST(scol.length AS VARCHAR) END, CAST((CASE WHEN scol.status = 128 THEN 1 ELSE 0 END) AS BIT) AS ""IsIdentity"", COALESCE(prop.value, ''), CAST(scol.isnullable AS BIT), COALESCE(syscom.text, '') AS ""DefaultValue"" FROM sysobjects so JOIN syscolumns scol ON (so.id = scol.id) JOIN systypes stype ON (scol.xtype = stype.xusertype) LEFT JOIN sys.extended_properties prop ON (prop.major_id = scol.id AND prop.minor_id = scol.colid AND prop.name = 'MS_Description') LEFT JOIN syscomments syscom ON (scol.cdefault > 0 AND scol.cdefault = syscom.id) WHERE so.name = '{ - name - }' AND so.xtype = 'u' AND stype.xusertype != 256 ORDER BY scol.colorder"; + $@"SELECT scol.name, stype.name, CASE stype.name WHEN 'decimal' THEN CAST(scol.xprec AS VARCHAR)+','+CAST(scol.xscale AS VARCHAR) ELSE CAST(scol.length AS VARCHAR) END, CAST((CASE WHEN scol.status = 128 THEN 1 ELSE 0 END) AS BIT) AS ""IsIdentity"", COALESCE(prop.value, ''), CAST(scol.isnullable AS BIT), COALESCE(syscom.text, '') AS ""DefaultValue"" FROM sysobjects so JOIN syscolumns scol ON (so.id = scol.id) JOIN systypes stype ON (scol.xtype = stype.xusertype) LEFT JOIN sys.extended_properties prop ON (prop.major_id = scol.id AND prop.minor_id = scol.colid AND prop.name = 'MS_Description') LEFT JOIN syscomments syscom ON (scol.cdefault > 0 AND scol.cdefault = syscom.id) WHERE so.id = { + id + } AND so.xtype = 'u' AND stype.xusertype != 256 ORDER BY scol.colorder"; else cmd.CommandText = - $@"SELECT scol.name, stype.name, CASE stype.name WHEN 'decimal' THEN CAST(scol.xprec AS VARCHAR)+','+CAST(scol.xscale AS VARCHAR) ELSE CAST(scol.length AS VARCHAR) END, CAST((CASE WHEN scol.status = 128 THEN 1 ELSE 0 END) AS BIT) AS ""IsIdentity"", '', CAST(scol.isnullable AS BIT), '' AS ""DefaultValue"" FROM sysobjects so JOIN syscolumns scol ON (so.id = scol.id) JOIN systypes stype ON (scol.xtype = stype.xusertype) WHERE so.name = '{ - name - }' AND so.xtype = 'u' AND stype.xusertype != 256 ORDER BY scol.colorder"; + $@"SELECT scol.name, stype.name, CASE stype.name WHEN 'decimal' THEN CAST(scol.xprec AS VARCHAR)+','+CAST(scol.xscale AS VARCHAR) ELSE CAST(scol.length AS VARCHAR) END, CAST((CASE WHEN scol.status = 128 THEN 1 ELSE 0 END) AS BIT) AS ""IsIdentity"", '', CAST(scol.isnullable AS BIT), '' AS ""DefaultValue"" FROM sysobjects so JOIN syscolumns scol ON (so.id = scol.id) JOIN systypes stype ON (scol.xtype = stype.xusertype) WHERE so.id = { + id + } AND so.xtype = 'u' AND stype.xusertype != 256 ORDER BY scol.colorder"; using (var rdr = cmd.ExecuteReader()) { while (rdr.Read()) diff --git a/Forms/DatabaseObjectBrowser.cs b/Forms/DatabaseObjectBrowser.cs index 43af055..e081272 100644 --- a/Forms/DatabaseObjectBrowser.cs +++ b/Forms/DatabaseObjectBrowser.cs @@ -57,9 +57,11 @@ private void LoadDatabaseObjects(ConnectionData connectionData) cmd.CommandText = QueryBuilder.SystemQueries.GetTableListWithRowCounts(); using (var rdr = cmd.ExecuteReader()) { - while (rdr.Read()) tables.Add(new TableInfo {Name = rdr.GetString(0), RowCount = rdr.GetInt64(1)}); + while (rdr.Read()) tables.Add(new TableInfo {Schema = rdr.GetString(0), Name = rdr.GetString(1), Id = rdr.GetInt32(2), RowCount = rdr.GetInt64(3)}); } + tables = tables.OrderBy(t => t.NameWithNonDefaultSchema).ToList(); + try { cmd.CommandText = QueryBuilder.SystemQueries.GetStoredProcList(); @@ -113,14 +115,15 @@ private void BuildVisibleDatabaseObjectList(string filterText) ContextMenuStrip = cmnTableCommandsGlobal }; foreach (var tableInfo in - tables.Where(t => t.Name.ToLower().Contains(filterText) && t.RowCount >= Settings_MinimumRowCount)) + tables.Where(t => t.NameWithNonDefaultSchema.ToLower().Contains(filterText) && t.RowCount >= Settings_MinimumRowCount)) tablesRootNode.Nodes.Add(new TreeNode { - Name = tableInfo.Name, + Name = tableInfo.NameWithNonDefaultSchema, Text = tableInfo.RowCount < int.MaxValue - ? $"{tableInfo.Name} ({tableInfo.RowCount})" - : tableInfo.Name, - ContextMenuStrip = cmnTableCommands + ? $"{tableInfo.NameWithNonDefaultSchema} ({tableInfo.RowCount})" + : tableInfo.NameWithNonDefaultSchema, + ContextMenuStrip = cmnTableCommands, + Tag = tableInfo.Id }); trvDatabaseObjects.Nodes.Add(tablesRootNode); } @@ -161,9 +164,9 @@ private void BuildVisibleDatabaseObjectList(string filterText) trvDatabaseObjects.SelectedNode = trvDatabaseObjects.Nodes["Tables"]; } - private void BuildTableFieldsOverview(string tableName) + private void BuildTableFieldsOverview(string tableName, long id) { - var table = new TableDefinition(tableName, currentConnectionData); + var table = new TableDefinition(tableName, id, currentConnectionData); splDatabaseObjects.Panel2Collapsed = false; dgvTableFields.SuspendLayout(); @@ -279,7 +282,7 @@ private void trvDatabaseObjects_AfterSelect(object sender, TreeViewEventArgs e) if (trvDatabaseObjects.SelectedNode != null && trvDatabaseObjects.SelectedNode.Parent != null && trvDatabaseObjects.SelectedNode.Parent.Name == "Tables") { - BuildTableFieldsOverview(trvDatabaseObjects.SelectedNode.Name); + BuildTableFieldsOverview(trvDatabaseObjects.SelectedNode.Name, (long)trvDatabaseObjects.SelectedNode.Tag); trvDatabaseObjects.SelectedNode.EnsureVisible(); } else @@ -300,13 +303,13 @@ private void trvDatabaseObjects_NodeMouseDoubleClick(object sender, TreeNodeMous var nodeName = trvDatabaseObjects.SelectedNode.Name; if (trvDatabaseObjects.SelectedNode.Parent.Name == "Tables") OnNewQueryInitiated(nodeName, - new TableDefinition(nodeName, currentConnectionData).BuildSelectQuery(QueryBuilder + new TableDefinition(nodeName, (long)trvDatabaseObjects.SelectedNode.Tag, currentConnectionData).BuildSelectQuery(QueryBuilder .TableSelectLimit.None)); else if (trvDatabaseObjects.SelectedNode.Parent.Name == "Procs") OnNewQueryInitiated(nodeName, procs.Single(p => p.Name == nodeName).Content); else if (trvDatabaseObjects.SelectedNode.Parent.Name == "Views") OnNewQueryInitiated(nodeName, - new TableDefinition(nodeName, currentConnectionData).BuildSelectQuery(QueryBuilder + new TableDefinition(nodeName, (long)trvDatabaseObjects.SelectedNode.Tag, currentConnectionData).BuildSelectQuery(QueryBuilder .TableSelectLimit.None)); } } @@ -327,7 +330,7 @@ private void trvDatabaseObjects_DragDrop(object sender, DragEventArgs e) var node = trvDatabaseObjects.GetHoverNode(e.X, e.Y); var values = e.Data.GetData(typeof(List)) as List; - var targetTable = new TableDefinition(node.Name, currentConnectionData); + var targetTable = new TableDefinition(node.Name, (long)node.Tag, currentConnectionData); var specimenValue = values.First(); OnNewQueryInitiated(node.Name, @@ -374,7 +377,7 @@ private void mniSelectAllRows_Click(object sender, EventArgs e) { var tableName = trvDatabaseObjects.SelectedNode.Name; OnNewQueryInitiated(tableName, - new TableDefinition(tableName, currentConnectionData).BuildSelectQuery(QueryBuilder.TableSelectLimit + new TableDefinition(tableName, (long)trvDatabaseObjects.SelectedNode.Tag, currentConnectionData).BuildSelectQuery(QueryBuilder.TableSelectLimit .None)); } @@ -388,7 +391,7 @@ private void mniSelectTopRows_Click(object sender, EventArgs e) { var tableName = trvDatabaseObjects.SelectedNode.Name; OnNewQueryInitiated(tableName, - new TableDefinition(tableName, currentConnectionData).BuildSelectQuery(QueryBuilder.TableSelectLimit + new TableDefinition(tableName, (long)trvDatabaseObjects.SelectedNode.Tag, currentConnectionData).BuildSelectQuery(QueryBuilder.TableSelectLimit .LimitTop)); } @@ -396,7 +399,7 @@ private void mniSelectBottomRows_Click(object sender, EventArgs e) { var tableName = trvDatabaseObjects.SelectedNode.Name; OnNewQueryInitiated(tableName, - new TableDefinition(tableName, currentConnectionData).BuildSelectQuery(QueryBuilder.TableSelectLimit + new TableDefinition(tableName, (long)trvDatabaseObjects.SelectedNode.Tag, currentConnectionData).BuildSelectQuery(QueryBuilder.TableSelectLimit .LimitBottom)); } @@ -404,21 +407,21 @@ private void mniCreateInsertQuery_Click(object sender, EventArgs e) { var tableName = trvDatabaseObjects.SelectedNode.Name; OnNewQueryInitiated($"{tableName} (i)", - new TableDefinition(tableName, currentConnectionData).BuildInsertQuery()); + new TableDefinition(tableName, (long)trvDatabaseObjects.SelectedNode.Tag, currentConnectionData).BuildInsertQuery()); } private void mniCreateUpdateQuery_Click(object sender, EventArgs e) { var tableName = trvDatabaseObjects.SelectedNode.Name; OnNewQueryInitiated($"{tableName} (u)", - new TableDefinition(tableName, currentConnectionData).BuildUpdateQuery()); + new TableDefinition(tableName, (long)trvDatabaseObjects.SelectedNode.Tag, currentConnectionData).BuildUpdateQuery()); } private void mniCreateDeleteQuery_Click(object sender, EventArgs e) { var tableName = trvDatabaseObjects.SelectedNode.Name; OnNewQueryInitiated($"{tableName} (d)", - new TableDefinition(tableName, currentConnectionData).BuildDeleteQuery()); + new TableDefinition(tableName, (long)trvDatabaseObjects.SelectedNode.Tag, currentConnectionData).BuildDeleteQuery()); } private void mniShowViewDefinition_Click(object sender, EventArgs e) @@ -440,8 +443,11 @@ private void mniGrantExecuteOnSP_Click(object sender, EventArgs e) private class TableInfo { + public long Id { get; set; } + public string Schema { get; set; } public string Name { get; set; } public long RowCount { get; set; } + public string NameWithNonDefaultSchema => Schema == "dbo" ? Name : $"{Schema}.{Name}"; } private class StoredProc diff --git a/SQLQueryTool.csproj b/SQLQueryTool.csproj index 63871bc..67360f8 100644 --- a/SQLQueryTool.csproj +++ b/SQLQueryTool.csproj @@ -33,6 +33,7 @@ 1.0.0.%2a false true + 6 true