2009-09-15 24 views
6

Come si può interrogare SQL Server per la data di creazione per una colonna di tabella di SQL Server 2005?Trova la data/l'ora in cui è stata creata la colonna di un tavolo

Ho provato il sp_columns [tablename] per ottenere quell'informazione, ma la data di creazione non è stata inclusa in questa stored procedure.

Come si può fare?

+0

Si dovrebbe guardare SYS.OBJECTS unito a SYS.COLUMNS. SYS.OBJECTS ha il campo create_date: http://technet.microsoft.com/en-us/library/ms190324.aspx –

risposta

5

C'è questa tabella di sistema denominata sys.Columns da cui è possibile ottenere informazioni sulle colonne. se volete vedere le colonne di una tabella particolare si può fare come segue:

SELECT col.* from sys.objects obj 
inner join sys.columns col 
on obj.object_Id=col.object_Id 
and [email protected] 

Oppure si può ottenere le informazioni tabella come questa:

SELECT * FROM sys.objects WHERE [email protected] 

ma non ho trovato alcuna informazione sulla creazione data di una colonna.

Aggiornamento: This potrebbe aiutare.

+0

perché non utilizzare "sys.tables" per le informazioni della tabella ?? Perché andare sempre a sys.objects ??? –

+0

Non lo so! Immagino che sia una vecchia abitudine :) – Beatles1692

+2

+1 - la data di creazione della colonna non sembra essere disponibile e per il collegamento fornito – AdaTheDev

0
SELECT obj.create_date 
from sys.objects obj 
inner join sys.columns col on obj.object_Id=col.object_Id 
WHERE col.name = @columnName 
and [email protected] 

edificio sulla risposta precedente, ma dando solo la data di creazione della colonna

+0

sì che sembra giusto – CRice

+0

se sto cercando informazioni sulla tabella, in genere preferisco usare sys.tables invece di sys.objects: è più mirato e non si seleziona accidentalmente qualcos'altro come un trigger o simile :-) –

+8

Questa è la data di creazione della tabella, non la data di creazione della colonna. Credo che Beatles1692 sia corretto, in SQL 2005 avresti bisogno di usare i trigger DDL per il suo link. – AdaTheDev

1

penso che ci sia alcun modo di ottenere la modifica o la data di creazione di singole colonne per sé. Le query fornite nella risposta this e this restituiscono le date relative a Tabella contenente la colonna e non la colonna. Perché la tabella sys.columns ha lo stesso id per tutte le colonne nella tabella. È possibile verificare ciò eseguendo questa query

select col.object_id, col.name, col.column_id 
from sys.columns col 
where col.object_id = 
(select o.object_id from sys.objects o where o.Name = @tableName) 
+1

o: dove col.object_id = OBJECT_ID ('table_name') - mi sembra più facile –

0

Non credo che questa informazione è disponibile se non si ha qualcosa che può passare in rassegna i registri delle transazioni, come Log Explorer. Non è una cosa tsql.

1

Un po 'in ritardo alla festa, ma ho trovato qualcosa che mi ha aiutato. Se si può dire che la colonna è l'ultima modifica alla tabella, allora sys.tables(modify_date) è praticabile.

6

SQL Server non tiene traccia delle modifiche specifiche alle tabelle. Se si desidera o si ha bisogno di questo livello di dettaglio, è necessario creare un trigger DDL (introdotto in SQL Server 2005) che possa intercettare determinati eventi specifici o anche classi di eventi e registrare tali modifiche in una tabella della cronologia creata.

DDL I trigger sono trigger "dopo"; non esiste un'opzione "invece di". Tuttavia, se si desidera disabilitare un'azione, è sufficiente emettere un numero ROLLBACK e questo annullerà l'evento.

La pagina di MSDN per DDL Triggers ha un sacco di buone informazioni riguardo alle modalità di intrappolare o eventi specifici (cioè ALTER TABLE) e utilizzando la funzione di EVENTDATA, che restituisce XML, per ottenere le specifiche di quale evento sparato il grilletto, tra cui l'esatto Query SQL che è stata eseguita. Infatti, la pagina MSDN per Use the EVENTDATA Function ha anche semplici esempi di creazione di un trigger DDL per acquisire le istruzioni ALTER TABLE (nella sezione " ALTER TABLE e ALTER DATABASE Events") e creare un trigger DDL per acquisire gli eventi in una tabella di log (in la sezione "Esempio"). Poiché tutti i comandi ALTER TABLE generano questo trigger, è necessario analizzare quali sono specifici per ciò che si sta cercando. E, forse ora che sai che questa è un'opzione, è necessario catturare più di una semplice aggiunta di colonne (ad esempio, rilasciare colonne, cambiare il tipo di dati e/o NULLability, ecc.).

Si noti che è possibile creare un trigger DLL ON ALL SERVER per eventi nell'ambito del database come ALTER_TABLE.

Se volete vedere la struttura del XML per qualsiasi evento o classe di evento, vai a:

http://schemas.microsoft.com/sqlserver/2006/11/eventdata/

e cliccare sul pulsante "Versione corrente:" collegamento. Se vuoi vedere un evento o una classe di eventi specifici, fai una ricerca (solitamente Control-F nel browser) sul nome dell'evento che verrebbe utilizzato nella clausola "FOR" del trigger (incluso il trattino basso). Quello che segue è lo schema per l'evento ALTER_TABLE:

<xs:complexType name="EVENT_INSTANCE_ALTER_TABLE"> 
<xs:sequence> 
<!-- Basic Envelope --> 
<xs:element name="EventType" type="SSWNAMEType"/> 
<xs:element name="PostTime" type="xs:string"/> 
<xs:element name="SPID" type="xs:int"/> 
<!-- Server Scoped DDL --> 
<xs:element name="ServerName" type="PathType"/> 
<xs:element name="LoginName" type="SSWNAMEType"/> 
<!-- DB Scoped DDL --> 
<xs:element name="UserName" type="SSWNAMEType"/> 
<!-- Main Body --> 
<xs:element name="DatabaseName" type="SSWNAMEType"/> 
<xs:element name="SchemaName" type="SSWNAMEType"/> 
<xs:element name="ObjectName" type="SSWNAMEType"/> 
<xs:element name="ObjectType" type="SSWNAMEType"/> 
<xs:element name="Parameters" type="EventTag_Parameters" minOccurs="0"/> 
<xs:element name="AlterTableActionList" type="AlterTableActionListType" minOccurs="0"/> 
<xs:element name="TSQLCommand" type="EventTag_TSQLCommand"/> 
</xs:sequence> 
</xs:complexType> 

Ecco un semplice test per vedere come funziona e ciò che la risultante EventData XML assomiglia:

IF (EXISTS(
    SELECT * 
    FROM sys.server_triggers sst 
    WHERE sst.name = N'CaptureAlterTable' 
    )) 
BEGIN 
    DROP TRIGGER CaptureAlterTable ON ALL SERVER; 
END; 
GO 

CREATE TRIGGER CaptureAlterTable 
ON ALL SERVER -- capture events for all databases 
FOR ALTER_TABLE -- only capture ALTER TABLE events 
AS 
    PRINT CONVERT(NVARCHAR(MAX), EVENTDATA()); -- Display in "Messages" tab in SSMS 
GO 

Prima creiamo una semplice, tabella reale in tempdb (questi eventi non vengono catturati per le tabelle temporanee):

USE [tempdb]; 
CREATE TABLE dbo.MyAlterTest (Col2 INT NULL); 

Successivamente aggiungiamo una colonna. Facciamo questo da un database diverso per assicurarci che l'XML catturi il database in cui l'oggetto esiste invece il database corrente. Si prega di notare l'involucro delle parole alTeR Table tempDB.dbo.MyALTERTest ... DATEcreated da confrontare con ciò che è nell'XML.

USE [master]; 
alTeR Table tempDB.dbo.MyALTERTest ADD DATEcreated DATETIME NOT NULL; 

si dovrebbe vedere il seguente nella scheda "Messaggi" (i commenti aggiunti da me):

<EVENT_INSTANCE> 
    <EventType>ALTER_TABLE</EventType> 
    <PostTime>2014-12-15T10:53:04.523</PostTime> 
    <SPID>55</SPID> 
    <ServerName>_{server_name}_</ServerName> 
    <LoginName>_{login_name}_</LoginName> 
    <UserName>dbo</UserName> 
    <DatabaseName>tempdb</DatabaseName> <!-- casing is based on database definition --> 
    <SchemaName>dbo</SchemaName> 
    <ObjectName>MyAlterTest</ObjectName> <!-- casing is based on object definition --> 
    <ObjectType>TABLE</ObjectType> 
    <AlterTableActionList> 
    <Create> 
     <Columns> 
     <Name>DATEcreated</Name> <!-- casing is taken from executed query --> 
     </Columns> 
    </Create> 
    </AlterTableActionList> 
    <TSQLCommand> 
    <SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE"/> 
    <CommandText>alTeR Table tempDB.dbo.MyALTERTest ADD DATEcreated DATETIME NOT NULL;&#x0D; 
</CommandText> 
    </TSQLCommand> 
</EVENT_INSTANCE> 

Sarebbe stato bello se i dettagli per-colonna (ad esempio NULL/NOT NULL, datatype, ecc.) sono stati acquisiti invece del solo nome, ma se necessario, questi possono essere analizzati dall'elemento CommandText.

1
SELECT so.name,so.modify_date 
FROM sys.objects as so 
    INNER JOIN INFORMATION_SCHEMA.TABLES as ist 
ON ist.TABLE_NAME=so.name where ist.TABLE_TYPE='BASE TABLE' AND 
TABLE_CATALOG='dbName' order by so.modify_date desc; 
Problemi correlati