从c#确定SQL Server数据库列的默认值

时间:2022-04-10 15:32:48

I need to find the default value of a column in a SQL Server 2005 or 2008 database from .Net.

我需要从。net找到SQL Server 2005或2008数据库中列的默认值。

My first attempt was to execute the stored procedure:

我的第一次尝试是执行存储过程:

sp_help @objname

Where @objname is the table. Then in the seventh table returned (the constraints table), I was going to use the value in constraint_keys for the default constraints. When I run this query from SQL Server Management Studio it behaves as intended, but when I run it from C# code, the column constraint_keys was null (although all the other columns were populated).

其中@objname是表。然后在返回的第7个表(约束表)中,我将使用constraint_keys中的值作为默认约束。当我从SQL Server Management Studio运行这个查询时,它的行为符合预期,但是当我从c#代码运行它时,列constraint_keys为null(尽管填充了所有其他列)。

My second attempt was to use:

我的第二次尝试是:

SELECT name, [text]
FROM syscomments com
    INNER JOIN syscolumns col ON com.id = col.cdefault
WHERE col.id = object_id(@Table)
    AND col.cdefault > 0

Which also works fine in SQL Server Management Studio. When I run it from .Net, however, it returns no rows.

在SQL Server Management Studio中也可以很好地工作。然而,当我从。net运行它时,它不会返回任何行。

Additional:

附加:

Example .Net code (using Enterprise Libraries):

示例。net代码(使用企业库):

    private DataTable GetDefaults(string tablename string database)
    {            
        var db = DatabaseEL.Create(database);

        string sql = @"
            SELECT name, [text]
            FROM syscomments com
                INNER JOIN syscolumns col ON com.id = col.cdefault
            WHERE col.id = object_id(@Table)
                AND col.cdefault > 0";

        using (var command = db.GetSqlStringCommand(sql))
        {
            db.AddInParameter(command, "@Table", DbType.String, tablename);

            return db.ExecuteDataTable(command);
        }
    }

Note that I have now also tried each of the following from the linked similar question:

请注意,我现在也从相关的类似问题中尝试了以下每一个问题:

SELECT 
name, object_definition(default_object_id) AS default_value
FROM sys.columns
WHERE object_id = object_id(@Table)
AND default_object_id != 0

and

SELECT
sc.name AS column_name, 
    sm.text AS default_value
FROM sys.sysobjects so
    JOIN sys.syscolumns sc ON sc.id = so.id
    LEFT JOIN sys.syscomments SM ON sm.id = sc.cdefault
WHERE so.xtype = 'U' 
AND SO.name = @Table
AND sm.text IS NOT NULL

They both worked in SSMS, but in .Net, the former had nulls in the default_value column, and the latter had no rows.

它们都在SSMS中工作,但是在。net中,前者在default_value列中有null,而后者没有行。

5 个解决方案

#1


3  

The answer seems to be to grant the user access to the db_ddladmin role. While db_datareader and db_datawriter are enough to run the necessary queries, they all return NULLs for default values if the user has no access to db_ddladmin.

答案似乎是授予用户对db_ddladmin角色的访问权。虽然db_datareader和db_datawriter足够运行必要的查询,但是如果用户没有访问db_ddladmin的权限,它们都会返回默认值的null。

The reason it worked for me from SQL Server Management Studio, of course, was because I was logged in as an administrative user.

从SQL Server Management Studio中为我工作的原因当然是我作为一个管理用户登录了。

#2


1  

One other SQL query you could try is:

您可以尝试的另一个SQL查询是:

select * from information_schema.columns
where table_catalog = 'MyDatabase'
and table_schema = 'dbo' -- or your schema
and table_name = 'MyTable';

The COLUMN_HASDEFAULT and COLUMN_DEFAULT values should give you the info you're looking for.

COLUMN_HASDEFAULT和COLUMN_DEFAULT值应该提供您正在寻找的信息。

#3


1  

You can use the GetSchema method from the SqlConnection.

您可以使用来自SqlConnection的GetSchema方法。

从c#确定SQL Server数据库列的默认值

#4


0  

Use SqlCommand to do it. try:

使用SqlCommand完成。试一试:

System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
        cmd.CommandText = "MyTable";
        cmd.CommandType = System.Data.CommandType.TableDirect;
        cmd.ExecuteReader(System.Data.CommandBehavior.SchemaOnly);

#5


0  

With this straight ADO.NET code, you can definitely retrieve the information needed, no problem:

直ADO。NET代码,您绝对可以检索所需的信息,没有问题:

public class ColumnAndDefault
{
    public string ColumnName { get; set; }
    public string DefaultDefinition { get; set; }
}

public class GetDefaultColumnValues
{
    public List<ColumnAndDefault> GetDefaultsForTable(string tablename, string connectionString)
    {
        List<ColumnAndDefault> results = new List<ColumnAndDefault>();

        string query =
            string.Format("SELECT name, object_definition(default_object_id) " +
            "FROM sys.columns " +
            "WHERE default_object_id <> 0 AND object_id = OBJECT_ID('{0}')", tablename);

        using(SqlConnection _con = new SqlConnection(connectionString))
        using(SqlCommand _cmd = new SqlCommand(query, _con))
        {
            _con.Open();

            using(SqlDataReader rdr = _cmd.ExecuteReader())
            {
                while(rdr.Read())
                {
                    if(!rdr.IsDBNull(0) && !rdr.IsDBNull(1))
                    {
                        string colName = rdr.GetString(0);
                        string defValue = rdr.GetString(1);

                        results.Add(
                           new ColumnAndDefault { ColumnName = colName, 
                                                  DefaultDefinition = defValue });
                    }
                }

                rdr.Close();
            }

            _con.Close();
        }


        return results;
    }
}

You can call this from your app like this:

你可以从你的应用中这样调用:

static void Main(string[] args)
{
   // grab that from a config file in your real app!
   string connectionString = "server=(local);database=YourDB;Integrated Security=SSPI;";

   GetDefaultColumnValues getter = new GetDefaultColumnValues();

   List<ColumnAndDefault> columnDefaults = 
      getter.GetDefaultsForTable("YourTableNameHere", connectionString);
}

#1


3  

The answer seems to be to grant the user access to the db_ddladmin role. While db_datareader and db_datawriter are enough to run the necessary queries, they all return NULLs for default values if the user has no access to db_ddladmin.

答案似乎是授予用户对db_ddladmin角色的访问权。虽然db_datareader和db_datawriter足够运行必要的查询,但是如果用户没有访问db_ddladmin的权限,它们都会返回默认值的null。

The reason it worked for me from SQL Server Management Studio, of course, was because I was logged in as an administrative user.

从SQL Server Management Studio中为我工作的原因当然是我作为一个管理用户登录了。

#2


1  

One other SQL query you could try is:

您可以尝试的另一个SQL查询是:

select * from information_schema.columns
where table_catalog = 'MyDatabase'
and table_schema = 'dbo' -- or your schema
and table_name = 'MyTable';

The COLUMN_HASDEFAULT and COLUMN_DEFAULT values should give you the info you're looking for.

COLUMN_HASDEFAULT和COLUMN_DEFAULT值应该提供您正在寻找的信息。

#3


1  

You can use the GetSchema method from the SqlConnection.

您可以使用来自SqlConnection的GetSchema方法。

从c#确定SQL Server数据库列的默认值

#4


0  

Use SqlCommand to do it. try:

使用SqlCommand完成。试一试:

System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
        cmd.CommandText = "MyTable";
        cmd.CommandType = System.Data.CommandType.TableDirect;
        cmd.ExecuteReader(System.Data.CommandBehavior.SchemaOnly);

#5


0  

With this straight ADO.NET code, you can definitely retrieve the information needed, no problem:

直ADO。NET代码,您绝对可以检索所需的信息,没有问题:

public class ColumnAndDefault
{
    public string ColumnName { get; set; }
    public string DefaultDefinition { get; set; }
}

public class GetDefaultColumnValues
{
    public List<ColumnAndDefault> GetDefaultsForTable(string tablename, string connectionString)
    {
        List<ColumnAndDefault> results = new List<ColumnAndDefault>();

        string query =
            string.Format("SELECT name, object_definition(default_object_id) " +
            "FROM sys.columns " +
            "WHERE default_object_id <> 0 AND object_id = OBJECT_ID('{0}')", tablename);

        using(SqlConnection _con = new SqlConnection(connectionString))
        using(SqlCommand _cmd = new SqlCommand(query, _con))
        {
            _con.Open();

            using(SqlDataReader rdr = _cmd.ExecuteReader())
            {
                while(rdr.Read())
                {
                    if(!rdr.IsDBNull(0) && !rdr.IsDBNull(1))
                    {
                        string colName = rdr.GetString(0);
                        string defValue = rdr.GetString(1);

                        results.Add(
                           new ColumnAndDefault { ColumnName = colName, 
                                                  DefaultDefinition = defValue });
                    }
                }

                rdr.Close();
            }

            _con.Close();
        }


        return results;
    }
}

You can call this from your app like this:

你可以从你的应用中这样调用:

static void Main(string[] args)
{
   // grab that from a config file in your real app!
   string connectionString = "server=(local);database=YourDB;Integrated Security=SSPI;";

   GetDefaultColumnValues getter = new GetDefaultColumnValues();

   List<ColumnAndDefault> columnDefaults = 
      getter.GetDefaultsForTable("YourTableNameHere", connectionString);
}