8

का उपयोग कर प्राथमिक कुंजी बाधाएं मेरे पास डेटाबेस स्कीमा को गतिशील रूप से पहचानने के लिए ADO.NET का कुछ कोड है, मुझे क्या चाहिए कि GetSchema विधि का उपयोग करके अद्वितीय कॉलम बाधाओं और प्राथमिक कुंजी बाधाओं को प्राप्त करने के लिए मुझे क्या चाहिए SqlConnection। इस कोड है कि मैं है:कॉलम कैसे प्राप्त करें SqlConnection.GetSchema()

conn.Open();  
SqlCommand mSqlCommand = new SqlCommand("sp_pkeys", conn); 
mSqlCommand.CommandType = CommandType.StoredProcedure; 
mSqlCommand.Parameters.Add(
    "@table_name", SqlDbType.NVarChar).Value = tableName; 
SqlDataReader mReader = mSqlCommand.ExecuteReader(
    (CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly)); 
//ExecuteReader(); 
DataTable schema = mReader.GetSchemaTable(); 
mReader.Close(); 
conn.Close(); 

उत्तर

4

GetSchemaTable on SqlConnection करने के लिए कॉल जो आप इस यह पता लगाने की अनुमति देगा में कुछ भी नहीं है।

यह लग सकता है कि आप कर सकते हैं, IsKey स्तंभ मान है, जो कुछ भी है कि विशिष्ट तालिका में रिकॉर्ड की पहचान करने के लिए योगदान के लिए सच लौटना चाहिए इस्तेमाल करते हैं। हालांकि, IsKey स्तंभ (जोर मेरा) के लिए प्रलेखन से:

सच: स्तंभ rowset कि, एक साथ लिया में कॉलम का समूह में से एक, विशिष्ट पंक्ति की पहचान है। IsKey के साथ कॉलम का सेट पर सेट किया गया है, सही रूप से पंक्ति में एक पंक्ति की पहचान करना चाहिए। की कोई आवश्यकता नहीं है कि कॉलम का यह सेट कम से कम स्तंभों का सेट है। कॉलम का यह सेट बेस तालिका प्राथमिक कुंजी, एक अद्वितीय बाधा या अद्वितीय अनुक्रमणिका से उत्पन्न हो सकता है।

इस वजह से, आप गारंटी नहीं दे सकते कि यह प्राथमिक कुंजी प्रति-योगदान में योगदान देता है।

अब, अगर आपको आवश्यकता है तो विशिष्ट रूप से पंक्ति की पहचान करने के लिए कुछ है, तो IsKey ठीक है, क्योंकि प्राथमिक कुंजी हमेशा एक पंक्ति की विशिष्ट पहचान करने का तरीका नहीं है (उदाहरण के लिए आप एक अद्वितीय इंडेक्स के साथ प्राकृतिक पहचानकर्ता हो सकते हैं)। यहां तक ​​कि यदि आपके पास प्राथमिक कॉल और अन्य कॉलम के साथ एक अद्वितीय इंडेक्स है, तो संयोजन में उन सभी स्तंभों में मान हमेशा अद्वितीय होंगे।

हालांकि, यदि आपको विशेष रूप से प्राथमिक कुंजी बनाने वाले कॉलम को देखने की आवश्यकता है, तो GetSchemaTable आपको आवश्यक जानकारी नहीं देगा। इसके बजाय, आप प्राथमिक कुंजी बनाने में योगदान देने वाले कॉलम के नाम ढूंढने के लिए sp_pkeys सिस्टम संग्रहीत प्रक्रिया को कॉल कर सकते हैं।

+0

धन्यवाद reply.from के लिए अपने स्पष्टीकरण मुझे समझ नहीं आता क्या मैं पर मेरे ऊपर सी # बदलने की जरूरत है आप syntax.Will कहना plz क्या मैं अपने कोड पर बदलने की जरूरत है। धन्यवाद – shamim

+0

@ शामिम: 'sp_keys' संग्रहीत प्रक्रिया के लिए लिंक देखें, आपको तालिका के लिए प्राथमिक कुंजी बनाने वाले कॉलम प्राप्त करने के लिए इस संग्रहीत प्रक्रिया को कॉल करना होगा। – casperOne

+0

मेरे उपरोक्त वाक्यविन्यास में मैं sp_keys प्रक्रिया का उपयोग करता हूं, वहां मैं टेबल नाम पास करता हूं, मेरे डेटाटेबल में मुझे स्कीमा मिलती है लेकिन स्कीमा से मैं प्राथमिक कुंजी का पता लगाने में विफल रहता हूं। इसलिए मैं आपका सुझाव और मदद चाहता हूं। धन्यवाद – shamim

2

यदि किसी को अभी भी समाधान की आवश्यकता है तो मैंने इसके लिए एक फ़ंक्शन बनाया है, SQLLand में वह कथन शामिल है जिसे आप स्कीमा जानकारी प्राप्त करना चाहते हैं।

Public Shared Function TableFromCommand(ByVal Command As SqlCommand) As DataTable 

    Dim Cn As SqlConnection = Nothing 
    Dim Dt As DataTable 
    Dim Dr As SqlDataReader 
    Dim Column As DataColumn 
    Dim Answer As New DataTable 

    Try 
     Answer.TableName = "SearchTable" 
     Cn = New SqlConnection("Your connection string") 
     Cn.Open() 

     Command.Connection = Cn 
     For Each Prm As SqlParameter In Command.Parameters 
      If Prm.Direction = ParameterDirection.Input _ 
      OrElse Prm.Direction = ParameterDirection.InputOutput Then 
       Prm.Value = DBNull.Value 
      End If 
     Next 

     Dr = Command.ExecuteReader(CommandBehavior.SchemaOnly Or CommandBehavior.KeyInfo) 
     Dt = Dr.GetSchemaTable 
     Dim Keys As New List(Of DataColumn) 
     Dim ColumnsDic As New SortedDictionary(Of Integer, DataColumn) 

     For Each Row As DataRow In Dt.Rows 
      Column = New DataColumn 
      With Column 
       .ColumnName = Row("ColumnName").ToString 
       .DataType = Type.GetType(Row("DataType").ToString) 
       .AllowDBNull = CBool(Row("AllowDBNull")) 
       .Unique = CBool(Row("IsUnique")) 
       .ReadOnly = CBool(Row("IsReadOnly")) 

       If Type.GetType(Row("DataType").ToString) Is GetType(String) Then 
        .MaxLength = CInt(Row("ColumnSize")) 
       End If 

       If CBool(Row("IsIdentity")) = True Then 
        .AutoIncrement = True 
        .AutoIncrementSeed = -1 
        .AutoIncrementStep = -1 
       End If 

       If CBool(Row("IsKey")) = True Then 
        Keys.Add(Column) 
       End If 
      End With 

      ColumnsDic.Add(CInt(Row("ColumnOrdinal")), Column) 

      Answer.Columns.Add(Column) 
     Next 

     If Keys.Count > 0 Then 
      Answer.Constraints.Add("PrimaryKey", Keys.ToArray, True) 
     End If 
    Catch ex As Exception 
     MyError.Show(ex) 
    Finally 
     If Cn IsNot Nothing AndAlso Not Cn.State = ConnectionState.Closed Then 
      Cn.Close() 
     End If 
    End Try 

    Return Answer 

End Function 
0

अपने एसक्यूएलकनेक्शन पर GetSchema() को कॉल करने के बारे में क्या? collectionName="IndexColumns" और स्कीमा प्रतिबंधों की एक सूची का उपयोग करके आप GetSchema() का उपयोग कर इच्छित जानकारी का अनुरोध कर सकते हैं।

देखें:

एक बार मैं SqlConnection डेटाबेस नाम का उपयोग कर स्थापित किया गया, मेरे लिए काम किया है:

var connectionString = 
    string.Format("Server=.\\SQLEXPRESS;Database={0};Trusted_Connection=true", dbName); 
using (var sqlConnection = new SqlConnection(connectionString)) 
{ 
    sqlConnection.Open(); 
    DataTable tables = sqlConnection.GetSchema("Tables"); 
    foreach (DataRow tablesRow in tables.Rows) 
    { 
     string tableName = tablesRow["table_name"].ToString(); 
     Console.WriteLine(tableName); 
     var indexCols = sqlConnection.GetSchema("IndexColumns", 
      new string[] {dbName, null, tableName, "PK_" + tableName, null}); 
     foreach (DataRow indexColsRow in indexCols.Rows) 
      Console.WriteLine(" PK: {0}", indexColsRow["column_name"]); 
    } 
} 
2

आप प्राप्त कर सकते हैं primaryKeys, UniqueKeys और ForeignKeys और डेटा में सूचीबद्ध कोई अन्य स्कीमा इस आदेश द्वारा लौटाया गया: "connection.GetSchema (" MetaDataCollections ")"

एक कोड के नीचे जो आपको प्राथमिक कीज़ और अनन्यकिज़ (कुंजी नाम और कॉलम नाम) देता है।

सभी दस्तावेज़ देखो Here

public void Dotransfer() 
    { 
     var sourceSchema = new TableSchema(SourceConnectionString); 

    } 



    public class TableSchema 
    { 
     public TableSchema(string connectionString) 
     { 
      this.TableList = new List<string>(); 
      this.ColumnList = new List<Columns>(); 
      this.PrimaryKeyList = new List<PrimaryKey>(); 
      this.ForeignKeyList = new List<ForeignKey>(); 
      this.UniqueKeyList = new List<UniqueKey>(); 

      GetDataBaseSchema(connectionString); 

     } 

     public List<string> TableList { get; set; } 
     public List<Columns> ColumnList { get; set; } 
     public List<PrimaryKey> PrimaryKeyList { get; set; } 
     public List<UniqueKey> UniqueKeyList { get; set; } 
     public List<ForeignKey> ForeignKeyList { get; set; } 


     protected void GetDataBaseSchema(string ConnectionString) 
     { 
      using (SqlConnection connection = new SqlConnection(ConnectionString)) 
      { 

       System.Data.SqlClient.SqlConnectionStringBuilder builder = new System.Data.SqlClient.SqlConnectionStringBuilder(); 
       builder.ConnectionString = ConnectionString; 
       string server = builder.DataSource; 
       string database = builder.InitialCatalog; 

       connection.Open(); 


       DataTable schemaTables = connection.GetSchema("Tables"); 

       foreach (System.Data.DataRow rowTable in schemaTables.Rows) 
       { 
        String tableName = rowTable.ItemArray[2].ToString(); 
        this.TableList.Add(tableName); 

        string[] restrictionsColumns = new string[4]; 
        restrictionsColumns[2] = tableName; 
        DataTable schemaColumns = connection.GetSchema("Columns", restrictionsColumns); 

        foreach (System.Data.DataRow rowColumn in schemaColumns.Rows) 
        { 
         string ColumnName = rowColumn[3].ToString(); 
         this.ColumnList.Add(new Columns(){TableName= tableName, FieldName = ColumnName}); 
        } 

        string[] restrictionsPrimaryKey = new string[4]; 
        restrictionsPrimaryKey[2] = tableName; 
        DataTable schemaPrimaryKey = connection.GetSchema("IndexColumns", restrictionsColumns); 


        foreach (System.Data.DataRow rowPrimaryKey in schemaPrimaryKey.Rows) 
        { 
         string indexName = rowPrimaryKey[2].ToString(); 

         if (indexName.IndexOf("PK_") != -1) 
         { 
          this.PrimaryKeyList.Add(new PrimaryKey() 
          { 
           TableName = tableName, 
           FieldName = rowPrimaryKey[6].ToString(), 
           PrimaryKeyName = indexName 
          }); 
         } 

         if (indexName.IndexOf("UQ_") != -1) 
         { 
          this.UniqueKeyList.Add(new UniqueKey() 
          { 
           TableName = tableName, 
           FieldName = rowPrimaryKey[6].ToString(), 
           UniqueKeyName = indexName 
          }); 
         } 

        } 


        string[] restrictionsForeignKeys = new string[4]; 
        restrictionsForeignKeys[2] = tableName; 
        DataTable schemaForeignKeys = connection.GetSchema("ForeignKeys", restrictionsColumns); 


        foreach (System.Data.DataRow rowFK in schemaForeignKeys.Rows) 
        { 

         this.ForeignKeyList.Add(new ForeignKey() 
         { 
          ForeignName = rowFK[2].ToString(), 
          TableName = tableName, 
          // FieldName = rowFK[6].ToString() //There is no information 
         });     
        } 


       } 


      } 

     } 

    }  

    public class Columns 
    { 
     public string TableName { get; set; } 
     public string FieldName { get; set; } 
    } 

    public class PrimaryKey 
    { 
     public string TableName { get; set; } 
     public string PrimaryKeyName { get; set; } 
     public string FieldName { get; set; } 
    } 


    public class UniqueKey 
    { 
     public string TableName { get; set; } 
     public string UniqueKeyName { get; set; } 
     public string FieldName { get; set; } 
    } 

    public class ForeignKey 
    { 
     public string TableName { get; set; } 
     public string ForeignName { get; set; } 
     // public string FieldName { get; set; } //There is no information 
    }