如何检索 SQL table 中所有列的所有约束名称
How to retreive all Constraint Names for all columns in a SQL table
我在 SQL 数据库的 Table 中添加了很多列。
现在,当我尝试从这个 Table 到 DROP
列的代码时,我收到一个错误,我必须首先 DROP the constraints
为我尝试 DROP
.[= 的实际列21=]
所以我的问题是如何 return 中列的所有约束名称:
Table:DateTimes
(在数据库中:DatabaseTest
).
我用谷歌搜索了这个,但没有找到如何执行此操作的直接代码示例。
我能找到的行是:
"show table status from " + databaseName + " where name = '" + datatableName + "';";
下面的代码不起作用,但我想知道是否可以将 return constraint names
table DateTimes
中所有列的代码完成?
谢谢!
void showContstraintsForTable()
{
String databaseName = "DatabaseTest";
String datatableName = "DateTimes";
using (SqlConnection conn = new SqlConnection(GetConnectionString()))
{
conn.Open();
String cmdString = "show table status from " + databaseName + " where name = '" + datatableName + "';";
using (SqlCommand comm = new SqlCommand(cmdString))
{
try
{
comm.Connection = conn;
//How to return all CONSTRAINTS for all columns in this table?
}
catch (SqlException ex) { MessageBox.Show(ex.ToString()); }
}
}
}
static private string GetConnectionString()
{
return "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\andre\source\repos\TestDatabaseCreation\DatabaseTest.mdf;Integrated Security=True;Connect Timeout=30";
}
以下获取外键约束,其中一种方法一次获取所有 table,而第二种方法仅获取 table。
希望如果这不是一个精确的解决方案,您可以通过一些代码或 sql 修改提供另一个想法。
原来SQL来了from this post
我使用 Windows 表单应用程序进行视觉处理,但不需要用户界面。
约束信息的容器
public class Constraints
{
public string TableName { get; set; }
public string ConstraintName { get; set; }
public string ColumnName { get; set; }
public string ReferencedTable { get; set; }
public string ReferencedColumn { get; set; }
public override string ToString() => TableName;
}
SQL 报表
public class QueryStatements
{
/// <summary>
/// Get all tables with foreign keys
/// </summary>
/// <returns></returns>
public static string ForeignKeysAllTables() =>
@"
SELECT
TableName = t.Name,constr.name AS ConstraintName, cols.name AS ColumnName, t2.name AS ReferencedTable, c2.name AS ReferencedColumn
FROM sys.tables t
INNER JOIN sys.foreign_keys constr ON constr.parent_object_id = t.object_id
INNER JOIN sys.tables t2 ON t2.object_id = constr.referenced_object_id
INNER JOIN sys.foreign_key_columns fkc ON fkc.constraint_object_id = constr.object_id
INNER JOIN sys.columns cols ON cols.object_id = fkc.parent_object_id AND cols.column_id = fkc.parent_column_id
INNER JOIN sys.columns c2 ON c2.object_id = fkc.referenced_object_id AND c2.column_id = fkc.referenced_column_id
ORDER BY t.Name, cols.name;
";
/// <summary>
/// Get foreign keys for a single table
/// </summary>
/// <returns></returns>
public static string ForeignKeysForSingleTable() =>
@"
SELECT
TableName = t.Name,constr.name AS ConstraintName, cols.name AS ColumnName, t2.name AS ReferencedTable, c2.name AS ReferencedColumn
FROM sys.tables t
INNER JOIN sys.foreign_keys constr ON constr.parent_object_id = t.object_id
INNER JOIN sys.tables t2 ON t2.object_id = constr.referenced_object_id
INNER JOIN sys.foreign_key_columns fkc ON fkc.constraint_object_id = constr.object_id
INNER JOIN sys.columns cols ON cols.object_id = fkc.parent_object_id AND cols.column_id = fkc.parent_column_id
INNER JOIN sys.columns c2 ON c2.object_id = fkc.referenced_object_id AND c2.column_id = fkc.referenced_column_id
WHERE t.name = @TableName
ORDER BY t.Name, cols.name;
";
/// <summary>
/// Get all table names in a database
/// </summary>
/// <param name="databaseName"></param>
/// <returns></returns>
public static string GetTableNames(string databaseName) =>
$"SELECT TABLE_NAME FROM [{databaseName}].INFORMATION_SCHEMA.TABLES " +
"WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME <> 'sysdiagrams' ORDER BY TABLE_NAME";
}
数据class
public class Informational
{
/// <summary>
/// For a real app the connection string could come
/// from app.config, adjust as needed
/// </summary>
private static string _databaseName = "NorthWind2020";
private static string _connectionString =
"Data Source=.\SQLEXPRESS;" +
$"Initial Catalog={_databaseName};" +
"Integrated Security=True";
public static List<Constraints> GetAllTablesForeignConstraints()
{
var results = new List<Constraints>();
using (var cn = new SqlConnection {ConnectionString = _connectionString})
{
using (var cmd = new SqlCommand {Connection = cn})
{
cmd.CommandText = QueryStatements.ForeignKeysAllTables();
cn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
results.Add(new Constraints()
{
TableName = reader.GetString(0),
ConstraintName = reader.GetString(1),
ColumnName = reader.GetString(2),
ReferencedTable = reader.GetString(3),
ReferencedColumn = reader.GetString(4)
});
}
}
}
return results;
}
public static List<Constraints> GetTableForeignConstraints(string tableName)
{
var results = new List<Constraints>();
using (var cn = new SqlConnection { ConnectionString = _connectionString })
{
using (var cmd = new SqlCommand { Connection = cn })
{
cmd.CommandText = QueryStatements.ForeignKeysForSingleTable();
cmd.Parameters.AddWithValue("@TableName", tableName);
cn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
results.Add(new Constraints()
{
TableName = reader.GetString(0),
ConstraintName = reader.GetString(1),
ColumnName = reader.GetString(2),
ReferencedTable = reader.GetString(3),
ReferencedColumn = reader.GetString(4)
});
}
}
}
return results;
}
public static List<string> GetTableNameList()
{
var results = new List<string>();
using (var cn = new SqlConnection {ConnectionString = _connectionString})
{
using (var cmd = new SqlCommand {Connection = cn})
{
cmd.CommandText = QueryStatements.GetTableNames(_databaseName);
cn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
results.Add(reader.GetString(0));
}
}
}
return results;
}
}
在一个表单中,一个 ListBox 加载了 table 个名称(并不意味着它们有约束)和一个 TextBox 来显示信息。在选择更改带有 table 名称的列表框时,检索约束或通过按钮单击事件为一个 table 硬编码示例。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SqlServerUtilities;
namespace SqlServerUtilitiesFrontEnd
{
public partial class Form1 : Form
{
private List<Constraints> _constraints;
public Form1()
{
InitializeComponent();
Shown += Form1_Shown;
}
private void Form1_Shown(object sender, EventArgs e)
{
_constraints = Informational.GetAllTablesForeignConstraints();
TableNameListBox.DataSource = Informational.GetTableNameList();
DisplayForeignConstraintNames();
TableNameListBox.SelectedIndexChanged += TableNameListBox_SelectedIndexChanged;
}
private void TableNameListBox_SelectedIndexChanged(object sender, EventArgs e)
{
DisplayForeignConstraintNames();
}
private void DisplayForeignConstraintNames()
{
var constraints = _constraints
.Where(item => item.TableName == TableNameListBox.Text).ToList();
var sb = new StringBuilder();
foreach (var constraint in constraints)
{
sb.AppendLine($"{constraint.ConstraintName}, {constraint.ReferencedColumn}");
}
ResultsTextBox.Text = sb.Length == 0 ? "None" : sb.ToString();
}
private void GetCustomersForeignConstraintsButton_Click(object sender, EventArgs e)
{
var constraints = Informational.GetTableForeignConstraints("Customers");
var sb = new StringBuilder();
foreach (var constraint in constraints)
{
sb.AppendLine($"{constraint.ConstraintName}, {constraint.ReferencedColumn}");
}
ResultsTextBox.Text = sb.Length == 0 ? "None" : sb.ToString();
}
}
}
我将所有 classes 放在 class 项目中,因为 Windows Form 项目用于演示目的,而 class 项目包含所需内容。
我在 SQL 数据库的 Table 中添加了很多列。
现在,当我尝试从这个 Table 到 DROP
列的代码时,我收到一个错误,我必须首先 DROP the constraints
为我尝试 DROP
.[= 的实际列21=]
所以我的问题是如何 return 中列的所有约束名称:
Table:DateTimes
(在数据库中:DatabaseTest
).
我用谷歌搜索了这个,但没有找到如何执行此操作的直接代码示例。
我能找到的行是:
"show table status from " + databaseName + " where name = '" + datatableName + "';";
下面的代码不起作用,但我想知道是否可以将 return constraint names
table DateTimes
中所有列的代码完成?
谢谢!
void showContstraintsForTable()
{
String databaseName = "DatabaseTest";
String datatableName = "DateTimes";
using (SqlConnection conn = new SqlConnection(GetConnectionString()))
{
conn.Open();
String cmdString = "show table status from " + databaseName + " where name = '" + datatableName + "';";
using (SqlCommand comm = new SqlCommand(cmdString))
{
try
{
comm.Connection = conn;
//How to return all CONSTRAINTS for all columns in this table?
}
catch (SqlException ex) { MessageBox.Show(ex.ToString()); }
}
}
}
static private string GetConnectionString()
{
return "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\andre\source\repos\TestDatabaseCreation\DatabaseTest.mdf;Integrated Security=True;Connect Timeout=30";
}
以下获取外键约束,其中一种方法一次获取所有 table,而第二种方法仅获取 table。
希望如果这不是一个精确的解决方案,您可以通过一些代码或 sql 修改提供另一个想法。
原来SQL来了from this post
我使用 Windows 表单应用程序进行视觉处理,但不需要用户界面。
约束信息的容器
public class Constraints
{
public string TableName { get; set; }
public string ConstraintName { get; set; }
public string ColumnName { get; set; }
public string ReferencedTable { get; set; }
public string ReferencedColumn { get; set; }
public override string ToString() => TableName;
}
SQL 报表
public class QueryStatements
{
/// <summary>
/// Get all tables with foreign keys
/// </summary>
/// <returns></returns>
public static string ForeignKeysAllTables() =>
@"
SELECT
TableName = t.Name,constr.name AS ConstraintName, cols.name AS ColumnName, t2.name AS ReferencedTable, c2.name AS ReferencedColumn
FROM sys.tables t
INNER JOIN sys.foreign_keys constr ON constr.parent_object_id = t.object_id
INNER JOIN sys.tables t2 ON t2.object_id = constr.referenced_object_id
INNER JOIN sys.foreign_key_columns fkc ON fkc.constraint_object_id = constr.object_id
INNER JOIN sys.columns cols ON cols.object_id = fkc.parent_object_id AND cols.column_id = fkc.parent_column_id
INNER JOIN sys.columns c2 ON c2.object_id = fkc.referenced_object_id AND c2.column_id = fkc.referenced_column_id
ORDER BY t.Name, cols.name;
";
/// <summary>
/// Get foreign keys for a single table
/// </summary>
/// <returns></returns>
public static string ForeignKeysForSingleTable() =>
@"
SELECT
TableName = t.Name,constr.name AS ConstraintName, cols.name AS ColumnName, t2.name AS ReferencedTable, c2.name AS ReferencedColumn
FROM sys.tables t
INNER JOIN sys.foreign_keys constr ON constr.parent_object_id = t.object_id
INNER JOIN sys.tables t2 ON t2.object_id = constr.referenced_object_id
INNER JOIN sys.foreign_key_columns fkc ON fkc.constraint_object_id = constr.object_id
INNER JOIN sys.columns cols ON cols.object_id = fkc.parent_object_id AND cols.column_id = fkc.parent_column_id
INNER JOIN sys.columns c2 ON c2.object_id = fkc.referenced_object_id AND c2.column_id = fkc.referenced_column_id
WHERE t.name = @TableName
ORDER BY t.Name, cols.name;
";
/// <summary>
/// Get all table names in a database
/// </summary>
/// <param name="databaseName"></param>
/// <returns></returns>
public static string GetTableNames(string databaseName) =>
$"SELECT TABLE_NAME FROM [{databaseName}].INFORMATION_SCHEMA.TABLES " +
"WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME <> 'sysdiagrams' ORDER BY TABLE_NAME";
}
数据class
public class Informational
{
/// <summary>
/// For a real app the connection string could come
/// from app.config, adjust as needed
/// </summary>
private static string _databaseName = "NorthWind2020";
private static string _connectionString =
"Data Source=.\SQLEXPRESS;" +
$"Initial Catalog={_databaseName};" +
"Integrated Security=True";
public static List<Constraints> GetAllTablesForeignConstraints()
{
var results = new List<Constraints>();
using (var cn = new SqlConnection {ConnectionString = _connectionString})
{
using (var cmd = new SqlCommand {Connection = cn})
{
cmd.CommandText = QueryStatements.ForeignKeysAllTables();
cn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
results.Add(new Constraints()
{
TableName = reader.GetString(0),
ConstraintName = reader.GetString(1),
ColumnName = reader.GetString(2),
ReferencedTable = reader.GetString(3),
ReferencedColumn = reader.GetString(4)
});
}
}
}
return results;
}
public static List<Constraints> GetTableForeignConstraints(string tableName)
{
var results = new List<Constraints>();
using (var cn = new SqlConnection { ConnectionString = _connectionString })
{
using (var cmd = new SqlCommand { Connection = cn })
{
cmd.CommandText = QueryStatements.ForeignKeysForSingleTable();
cmd.Parameters.AddWithValue("@TableName", tableName);
cn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
results.Add(new Constraints()
{
TableName = reader.GetString(0),
ConstraintName = reader.GetString(1),
ColumnName = reader.GetString(2),
ReferencedTable = reader.GetString(3),
ReferencedColumn = reader.GetString(4)
});
}
}
}
return results;
}
public static List<string> GetTableNameList()
{
var results = new List<string>();
using (var cn = new SqlConnection {ConnectionString = _connectionString})
{
using (var cmd = new SqlCommand {Connection = cn})
{
cmd.CommandText = QueryStatements.GetTableNames(_databaseName);
cn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
results.Add(reader.GetString(0));
}
}
}
return results;
}
}
在一个表单中,一个 ListBox 加载了 table 个名称(并不意味着它们有约束)和一个 TextBox 来显示信息。在选择更改带有 table 名称的列表框时,检索约束或通过按钮单击事件为一个 table 硬编码示例。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SqlServerUtilities;
namespace SqlServerUtilitiesFrontEnd
{
public partial class Form1 : Form
{
private List<Constraints> _constraints;
public Form1()
{
InitializeComponent();
Shown += Form1_Shown;
}
private void Form1_Shown(object sender, EventArgs e)
{
_constraints = Informational.GetAllTablesForeignConstraints();
TableNameListBox.DataSource = Informational.GetTableNameList();
DisplayForeignConstraintNames();
TableNameListBox.SelectedIndexChanged += TableNameListBox_SelectedIndexChanged;
}
private void TableNameListBox_SelectedIndexChanged(object sender, EventArgs e)
{
DisplayForeignConstraintNames();
}
private void DisplayForeignConstraintNames()
{
var constraints = _constraints
.Where(item => item.TableName == TableNameListBox.Text).ToList();
var sb = new StringBuilder();
foreach (var constraint in constraints)
{
sb.AppendLine($"{constraint.ConstraintName}, {constraint.ReferencedColumn}");
}
ResultsTextBox.Text = sb.Length == 0 ? "None" : sb.ToString();
}
private void GetCustomersForeignConstraintsButton_Click(object sender, EventArgs e)
{
var constraints = Informational.GetTableForeignConstraints("Customers");
var sb = new StringBuilder();
foreach (var constraint in constraints)
{
sb.AppendLine($"{constraint.ConstraintName}, {constraint.ReferencedColumn}");
}
ResultsTextBox.Text = sb.Length == 0 ? "None" : sb.ToString();
}
}
}
我将所有 classes 放在 class 项目中,因为 Windows Form 项目用于演示目的,而 class 项目包含所需内容。