2011-02-23 69 views
2

我需要從.Net找到SQL Server 2005或2008數據庫中列的默認值。從C中確定SQL Server數據庫列的默認值#

我第一次嘗試以執行存儲過程:

sp_help @objname 

哪裏@objname是表。然後在返回的第七個表(約束表)中,我將使用constraint_keys中的值作爲默認約束。當我從SQL Server Management Studio運行這個查詢時,它的行爲像預期的那樣,但是當我從C#代碼運行它時,列constraint_keys爲空(儘管所有其他列都已填充)。

我的第二次嘗試使用:

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 

其中在SQL Server Management Studio中也能正常工作。但是,當我從.Net運行它時,它不返回任何行。

附加:

例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); 
     } 
    } 

注意,我現在還試圖從每個鏈接的類似的問題如下:

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 

他們都在SSMS中工作,但在.Net中,前者在default_value列中有空值,而後者沒有行。

+0

聽起來像是http://stackoverflow.com/q/3817885/559467的副本。這爲您提供了可以從C#運行的SQL語句中的值。如果它沒有默認值,它將不會返回任何內容。 – 2011-02-23 17:43:12

+0

你可以發佈.Net代碼嗎?我沒有任何意義,它是從管理工作室而不是從.Net工作。 – 2011-02-23 17:46:32

回答

3

答案似乎是授予用戶訪問​​角色的權限。雖然db_datareaderdb_datawriter足以運行必要的查詢,但如果用戶無法訪問​​,則它們都會返回NULL作爲默認值。

從SQL Server Management Studio中爲我工作的原因當然是因爲我是以管理用戶身份登錄的。

0

使用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); 
+0

我不認爲這在.NET 3.5中得到了支持。我得到了一個異常:「.Net Framework SqlClient數據提供程序不支持CommandType枚舉值512。」。 – Paul 2011-02-23 18:34:59

+0

嘗試只是一個SQL查詢,然後cmd.CommandText =「選擇頂部1 *從MyTable」; cmd.CommandType = Text; – 2011-02-23 19:12:51

1

另外一個SQL查詢,你可以嘗試是:

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

COLUMN_HASDEFAULTCOLUMN_DEFAULT值應該給你你正在尋找的信息。

+0

select * from information_schema.columns在SQL Server 2005中爲我返回SSMS中沒有行。 – Paul 2011-02-23 18:27:49

+0

嗯,有趣。不知道是什麼原因造成的,但我想這種方法在這種情況下不適合你。 – 2011-02-23 19:55:01

1

您可以使用SqlConnection中的GetSchema方法。

enter image description here

+0

不錯,這看起來比我的方法好一點。 – 2011-02-23 19:14:32

+0

這是優雅的,但仍然不適合我。該表填充了列,但COLUMN_DEFAULT列完全爲空。 – Paul 2011-02-23 21:26:12

0

有了這個直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; 
    } 
} 

您可以從您的應用程序調用該是這樣的:

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); 
} 
+0

這也沒有工作。在行string defValue = rdr.GetString(1);上有一個SqlNullValueException。 – Paul 2011-02-23 22:22:58

+0

@Paul:肯定有什麼東西在你的系統中可疑,然後.....無論如何:更新我的答案**檢查**爲NULL,並避免進入NULL情況 - 請再試一次。 – 2011-02-24 05:28:49

+0

是的,我同意。我認爲這是我係統中特有的東西。我可能不得不關閉觸發器,在事務中插入空行,選擇默認值並回滾:-S – Paul 2011-02-24 08:50:41