2009-09-15 5 views
6

Wie können Sie SQL Server für das Erstellungsdatum für eine SQL Server 2005-Tabellenspalte abfragen?Suchen Sie das Datum/die Uhrzeit, zu der die Spalte einer Tabelle erstellt wurde

Ich versuchte die sp_columns [tablename], um diese Informationen zu erhalten, aber das Erstellungsdatum war nicht in dieser gespeicherten Prozedur enthalten.

Wie kann das gemacht werden?

+0

Sie müssten sich SYS.OBJECTS ansehen, die mit SYS.COLUMNS verbunden sind. SYS.OBJECTS hat das create_date-Feld: http://technet.microsoft.com/en-us/library/ms190324.aspx –

Antwort

5

Es gibt diese Systemtabelle mit dem Namen sys.Columns, von der Spalteninformationen abgerufen werden können. wenn Sie Spalten einer bestimmten Tabelle sehen Sie, wie folgt tun:

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

Oder können Sie Tabelleninformationen wie diese:

SELECT * FROM sys.objects WHERE [email protected] 

aber ich keine Informationen über die Schöpfung finden konnten, Datum einer Spalte.

Aktualisiert: This könnte helfen.

+0

Warum nicht "sys.tables" für die Tabelleninformationen verwenden? Warum immer zu sys.objects gehen ??? –

+0

Ich weiß es nicht! Es ist eine alte Angewohnheit, die ich denke :) – Beatles1692

+2

+1 - Spalte Erstellungsdatum scheint nicht verfügbar zu sein und für Link zur Verfügung gestellt – 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] 

Gebäude auf der vorherige Antwort, aber nur das Erstellungsdatum der Spalte

+0

Ja, das sieht richtig aus – CRice

+0

Wenn ich nach Tabelleninformationen suche, bevorzuge ich in der Regel sys.tables statt sys.objects - es ist fokussierter und Sie wählen nicht zufällig etwas anderes wie einen Trigger oder so :-) –

+8

Dies ist das Erstellungsdatum der Tabelle, nicht das Erstellungsdatum der Spalte. Ich glaube, Beatles1692 ist korrekt, in SQL 2005 müssten Sie DDL-Trigger für seinen Link verwenden. – AdaTheDev

1

Ich denke, es gibt keinen Weg, um Änderung oder das Erstellungsdatum der einzelnen Spalten per se geben. Die Abfragen, die in this und this Antwort gegeben werden, gibt die Daten zurück, die sich auf Tabelle beziehen, die die Spalte nicht die Spalte enthält. Da die Tabelle sys.columns für alle Spalten in der Tabelle die gleiche ID hat. Sie können dies überprüfen, indem Sie diese Abfrage ausgeführt

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

oder: wo col.object_id = OBJECT_ID ('table_name') - scheint mir einfacher –

0

Ich glaube nicht, dass diese Informationen verfügbar sind, wenn Sie etwas haben, das die Transaktionsprotokolle, wie Log Explorer durchsuchen können. Es ist keine Tsql-Sache.

1

Bis spät in die Party, aber etwas gefunden, das mir geholfen hat. Wenn Sie sagen können, dass die Spalte die letzte Änderung an der Tabelle ist, ist sys.tables(modify_date) praktikabel.

6

Der SQL Server verfolgt keine spezifischen Änderungen an Tabellen. Wenn Sie diese Detaillierungsstufe benötigen oder benötigen, müssen Sie einen DDL-Trigger (eingeführt in SQL Server 2005) erstellen, der bestimmte Ereignisse oder sogar Ereignisklassen auffängt und diese Änderungen in einer von Ihnen erstellten Protokolltabelle protokolliert.

DDL-Trigger sind "nach" Trigger; Es gibt keine "statt" -Option. Wenn Sie jedoch eine Aktion ablehnen möchten, können Sie einfach ROLLBACK ausgeben und das wird abgebrochen.

Die MSDN-Seite für DDL Triggers hat viele gute Informationen darüber, wie zu stoppen entweder bestimmte Ereignisse (dh ALTER TABLE) und mit Hilfe der EVENTDATA Funktion, die XML zurückgibt, die Besonderheiten von dem, was Ereignis ausgelöst, den Abzug zu erhalten, einschließlich der genauen SQL-Abfrage, die ausgeführt wurde. Die MSDN-Seite für Use the EVENTDATA Function enthält sogar einfache Beispiele zum Erstellen eines DDL-Triggers zum Erfassen von ALTER TABLE Anweisungen (im Abschnitt " ALTER TABLE- und ALTER DATABASE-Ereignisse") und Erstellen eines DDL-Triggers zum Erfassen der Ereignisse in einer Protokolltabelle (in der Abschnitt "Beispiel"). Da alle ALTER TABLE Befehle diesen Trigger auslöst, müssen Sie analysieren, welche spezifisch für was Sie suchen. Und vielleicht wissen Sie jetzt, dass dies eine Option ist, das Erfassen von mehr als nur das Hinzufügen von Spalten ist erwünscht (d. H. Löschen von Spalten, Ändern des Datentyps und/oder der NULL-Fähigkeit usw.).

Es sollte beachtet werden, dass Sie einen DLL-Trigger ON ALL SERVER für datenbankspezifische Ereignisse wie ALTER_TABLE erstellen können.

Wenn Sie die Struktur des XML für jede Veranstaltung oder Ereignisklasse sehen möchten, gehen Sie zu:

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

und klicken Sie auf „Aktuelle Version:“ -Link. Wenn Sie eine bestimmte Ereignis- oder Ereignisklasse sehen möchten, führen Sie einfach eine Suche (normalerweise Control-F im Browser) nach dem Ereignisnamen durch, der in der FOR-Klausel des Triggers (einschließlich des Unterstrichs) verwendet wird. Hier finden Sie das Schema für die ALTER_TABLE Ereignis:

<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> 

Hier ist ein sehr einfacher Test, um zu sehen, wie das funktioniert und was die resultierende Eventdata XML wie folgt aussieht:

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 

Zuerst erstellen wir eine einfache, reale Tabelle in tempdb (diese Ereignisse werden nicht für temporäre Tabellen erfasst):

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

Als nächstes fügen wir eine Spalte hinzu. Wir tun dies aus einer anderen Datenbank, um sicherzustellen, dass die XML-Datei die Datenbank, in der das Objekt vorhanden ist, anstelle der aktuellen Datenbank erfasst. Bitte beachten Sie das Gehäuse der Wörter alTeR Table tempDB.dbo.MyALTERTest ... DATEcreated, um mit dem, was in der XML ist, zu vergleichen.

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

Folgendes sollten Sie im Register "Nachrichten" (von mir Kommentare hinzugefügt) sehen:

<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> 

Es würde, wenn die Details pro-Säule schön gewesen (dh NULL/NOT NULL, Datentyp, usw.) wurden nicht nur als Name, sondern bei Bedarf auch aus dem CommandText Element geparst.

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; 
Verwandte Themen