2010-08-23 10 views
5

Dato un database, come posso recuperare un elenco di tabelle insieme alla chiave primaria di ogni tabella?Come posso ottenere un elenco di tabelle in un database SQL Server insieme alla chiave primaria utilizzando SOLO C#?

Grazie.

Modifica: questo è per uno strumento di generazione del codice che sto creando, ho bisogno di eseguire in qualche modo lo script SQL usando solo C#.

+0

possibile duplicato di [Come ottenere l'elenco di tutte le tabelle in un database utilizzando TSQL?] (Http://stackoverflow.com/questions/175415/how-do-i-get-list-of-all-tables -in-a-database-using-tsql) –

+2

Non un duplicato. Voglio il codice C#, non TSQL. C'è una grande differenza. –

+4

@Sergio: il modo per farlo in C# è di eseguire uno script TSQL (ad esempio un SP). – Brian

risposta

6

Questo non utilizza T-SQL da solo. Lo genera da solo ma non sarà tanto efficiente quanto semplicemente usando il T-SQL esatto e corto che otterrà le stesse informazioni.

using Microsoft.SqlServer.Management.Common; 
using Microsoft.SqlServer.Management.Smo; 

public class LoadStuff 
{ 
    string mDatabaseConnectionString = "Something"; 
    ... 
    public void LoadDatabase(string tDatabaseName) 
    { 
     using (var vSqlConnection = new SqlConnection(mDatabaseConnectionString)) 
     { 
      var vConnection = new ServerConnection(vSqlConnection); 
      var vServer = new Server(vConnection); 
      var vDatabase = vServer.Databases[tDatabaseName]; 
      var vTables = vDatabase.Tables; 
     } 
    } 
} 

ciascuno degli oggetti della collezione "VTables" sarà una definizione per una tabella nel database denominato vDatabaseName.

Quella tabella avrà una raccolta di colonne e le chiavi primarie possono essere trovate eseguendo il ciclo attraverso la proprietà "Colonne" di ogni tabella. Qualsiasi colonna nella chiave primaria avrà la sua proprietà "InPrimaryKey" contrassegnata come vera.

Inoltre, è necessario ottenere tutte le informazioni dai vari oggetti PRIMA della fine del blocco. Ho iniziato a creare mini classi che contenevano solo le informazioni di cui avevo bisogno una volta terminato l'intero processo, ma probabilmente si può semplicemente sputare il codice dalla generazione del codice.

+1

Dipende da cosa intendi per "non usa T-SQL". Non c'è T-SQL nel codice, ma probabilmente sta eseguendo molto più T-SQL rispetto alle altre risposte che ottengono tutto ciò di cui abbiamo bisogno in una query. – stevemegson

+1

SMO genererebbe ed eseguirà il codice T-SQL richiesto per te e lo sviluppatore dell'app non dovrà preoccuparsi del codice effettivo, della gestione delle modifiche alla versione del database, dell'iniezione SQL, ecc. Una volta lanciati i loop per estrarre i dati bisogno di questo, si finisce con gli stessi risultati ... e se i * requisiti * sono "nessun T-SQL nel codice C#", allora questo è quello che ti serve. –

+0

Sì, stavo prendendo come non poteva usare T SQL per questo. O almeno deve usare il maggior numero possibile di # per farlo. Usa SQL ma la persona che usa questo frammento di codice usa solo il codice, nessuna stringa di comando o altro. – Rangoric

1

Ecco un inizio (SQL 2005 in su):

SELECT ta.name TableName, ind.name IndexName 
from sys.tables ta 
    left outer join sys.indexes ind 
    on ind.object_id = ta.object_id 
    and ind.is_primary_key = 1 

tabelle senza chiavi primarie devono IndexName impostato su Null.

Ma questo semplicemente elenca il nome della chiave primaria. Hai bisogno di un elenco delle colonne nella chiave?

- ha aggiunto ----------------

Ecco una parte di un programma di utilità, una volta che ho scritto. Questo elenco di tutte le tabelle e colonne in ordine di tutte le chiavi primarie esistenti:

SELECT ta.name TableName, ind.name IndexName, indcol.key_ordinal IndexColumnOrder, col.name ColumnName 
from sys.tables ta 
    left outer join sys.indexes ind 
    on ind.object_id = ta.object_id 
    and ind.is_primary_key = 1 
    left outer join sys.index_columns indcol 
    on indcol.object_id = ta.object_id 
    and indcol.index_id = ind.index_id 
    left outer join sys.columns col 
    on col.object_id = ta.object_id 
    and col.column_id = indcol.column_id 
order by 
    ta.Name 
    ,indcol.key_ordinal 

hacking che la seguente elenca tutti (e solo) tabelle con chiavi primarie di una sola colonna:

SELECT ta.name TableName, max(col.name) ColumnName 
from sys.tables ta 
    inner join sys.indexes ind 
    on ind.object_id = ta.object_id 
    and ind.is_primary_key = 1 
    inner join sys.index_columns indcol 
    on indcol.object_id = ta.object_id 
    and indcol.index_id = ind.index_id 
    inner join sys.columns col 
    on col.object_id = ta.object_id 
    and col.column_id = indcol.column_id 
group by ta.name 
having count(*) = 1 
order by ta.Name 

Per quanto riguarda la trasformazione in C# (non il mio forte), dovresti essere in grado di rendere questa una stored procedure, o semplicemente creare e inviare la query dal tuo codice.

+0

Immaginate che la tabella Persona abbia le colonne ID come chiave primaria. Ho bisogno del nome esatto di quella colonna. Devo anche richiamare in qualche modo questo all'interno del codice C#. Come posso fare questo? –

+0

Puoi fare riferimento alle colonne PK in base alla posizione ordinale (0,1) anziché al nome (ID, tipo)? – Beth

3

Ecco una risposta:

select 
    t.Table_Name, 
    tc.Constraint_Name, 
    ccu.Column_Name 
from 
    information_schema.tables t 
    left join information_schema.table_constraints tc 
     on tc.Table_Catalog = t.Table_Catalog 
     and tc.Table_Name = t.Table_Name 
     and tc.Constraint_Type = 'PRIMARY KEY' 
    left join information_schema.constraint_column_usage ccu 
     on ccu.Table_Catalog = tc.Table_Catalog 
     and ccu.Table_Name = tc.Table_Name 
     and ccu.Constraint_Schema = tc.Constraint_Schema 
     and ccu.Constraint_Name = tc.Constraint_Name 
order by 
    t.Table_Name, 
    tc.Constraint_Name, 
    ccu.Column_Name 

Questo elenco di tavoli, i loro vincoli di chiave primaria, e le colonne in quei vincoli. Nota che se una chiave primaria ha più colonne, ci saranno più voci per quella colonna. Si noti inoltre che questa query restituisce anche le viste.

+0

Ho bisogno di C#, non di TSQL. –

+0

L'utente non sta eseguendo comandi TSQL; il tuo codice C# è. Qual è la tua obiezione alla creazione di una connessione SQL e l'utilizzo di questo come il comando SQL in C#? Non c'è possibilità di iniezione SQL qui. –

0

Si utilizza l'oggetto SqlCommand per eseguire T-SQL su un database ..

qui documentata con molti esempi in C# e altri linguaggi: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.aspx

O vuoi dire direttamente utilizzando il CLR built nel server SQL?

+0

Non posso avere l'utente finale che esegue i comandi TSQL, ho bisogno di usare puro C#. –

+0

Capisci la relazione tra il server SQL e il framework dotnet? SQLCommand è fondamentale: quasi TUTTE le interazioni tra ANY dotnet application/framwork e SQL server avvengono attraverso quell'oggetto ... Per favore, spiega come immagini un'applicazione per interagire con un database !!!!!! Ho già deciso di non acquistare il tuo 'prodotto' – Adrian

+0

È molto possibile. L'esecuzione di una cosa di raccolta personalizzata non è fattibile, tuttavia esiste una libreria creata da MS che ha già informazioni sul database. È possibile ottenere praticamente tutte le informazioni non di dati che si desiderano su un database senza scrivere alcun T-SQL. – Rangoric

Problemi correlati