2009-09-15 18 views
6

¿Cómo se puede consultar SQL Server para la fecha de creación de una columna de tabla de SQL Server 2005?Encontrar la fecha/hora en que se creó la columna de una tabla

Probé el sp_columns [tablename] para obtener esa información, pero la fecha de creación no se incluyó en este procedimiento almacenado.

¿Cómo se puede hacer esto?

+0

Tendría que mirar SYS.OBJECTS unidos a SYS.COLUMNS. SYS.OBJECTS tiene el campo create_date: http://technet.microsoft.com/en-us/library/ms190324.aspx –

Respuesta

5

Hay esta tabla de sistema llamada sys.Columns de la que puede obtener información de columnas. si quieres ver columnas de una tabla en particular se puede hacer de la siguiente manera:

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

O puede obtener información de tabla de la siguiente manera:

SELECT * FROM sys.objects WHERE [email protected] 

pero no pude encontrar ninguna información sobre la creación fecha de una columna.

Actualizado: This puede ayudar.

+0

¿por qué no utiliza "sys.tables" para la información de la tabla? ¿Por qué siempre ir a sys.objects ??? –

+0

¡No sé! Es un viejo hábito, supongo :) – Beatles1692

+2

+1 - la fecha de creación de la columna no parece estar disponible y para el enlace proporcionado – 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 en la respuesta anterior, pero únicamente la fecha de la creación de la columna

+0

sí que se ve bien – CRice

+0

si estoy buscando información de la tabla, generalmente prefiero usar sys.tables en lugar de sys.objects: está más enfocado y no selecciona accidentalmente algo más como un disparador o algo similar :-) –

+8

Esta es la fecha de creación de la tabla, no la fecha de creación de la columna. Creo que Beatles1692 es correcto, en SQL 2005 necesitaría usar desencadenadores DDL por su enlace. – AdaTheDev

1

Creo que no hay manera de conseguir la modificación o creación fecha de columnas individuales per se. Las consultas dadas en this y this responden devuelve las fechas relacionadas con la Tabla que contiene la columna, no la columna. Porque la tabla sys.columns tiene la misma identificación para todas las columnas de la tabla. Esto se puede comprobar mediante la ejecución de esta consulta

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: donde col.object_id = OBJECT_ID ('table_name') - me parece más fácil –

0

No creo que esta información está disponible a menos que tenga algo que puede navegar por los registros de transacciones, como Log Explorer. No es una cosa de tsql.

1

Llegué tarde a la fiesta pero encontré algo que me ayudó. Si puede decir que la columna es el último cambio a la tabla, entonces sys.tables(modify_date) es realizable.

6

SQL Server no realiza un seguimiento de los cambios específicos en las tablas. Si desea o necesita este nivel de detalle, debe crear un desencadenador DDL (introducido en SQL Server 2005) que pueda atrapar ciertos eventos específicos o incluso clases de eventos, y registrar esos cambios en una tabla de historial que cree.

Los activadores DDL son desencadenantes "después"; no hay una opción "en lugar de". Sin embargo, si no desea permitir una acción, puede emitir un ROLLBACK y eso cancelará lo sucedido.

La página de MSDN para DDL Triggers tiene un montón de buena información sobre cómo atrapar ya sea eventos específicos (es decir ALTER TABLE) y utilizar la función EVENTDATA, que devuelve XML, para obtener los detalles de lo evento disparado el gatillo, incluyendo la exacta Consulta SQL que se ejecutó. De hecho, la página de MSDN para Use the EVENTDATA Function incluso tiene ejemplos simples de crear un desencadenador DDL para capturar declaraciones ALTER TABLE (en la sección "ALTER TABLE y ALTER DATABASE Events") y crear un desencadenador DDL para capturar los eventos en una tabla de registro (en la sección "Ejemplo"). Como todos los comandos ALTER TABLE dispararán este desencadenador, debe analizar cuáles son específicos de lo que está buscando. Y, tal vez ahora que sabe que esta es una opción, se desea capturar algo más que simplemente agregar columnas (es decir, eliminar columnas, cambiar el tipo de datos y/o NULLability, etc.).

Debe tenerse en cuenta que puede crear un desencadenador DLL ON ALL SERVER para eventos con base en la base de datos como ALTER_TABLE.

Si quieres ver la estructura del XML para cualquier evento o clase de evento, ir a:

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

y hacer clic en la "versión actual:" enlace. Si desea ver un evento o clase de evento específico, simplemente haga una búsqueda (generalmente Control-F en el navegador) en el nombre del evento que se usaría en la cláusula "FOR" del desencadenador (incluido el guión bajo). El siguiente es el esquema para el 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> 

Aquí es una prueba muy simple para ver cómo funciona esto y lo que el XML EventData resultante se parece a:

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 

Primero creamos un simple, tabla real en tempdb (estos eventos no se capturan para tablas temporales):

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

A continuación, agregamos una columna. Hacemos esto desde una base de datos diferente para asegurarnos de que el XML capture la base de datos donde existe el objeto en lugar de la base de datos actual. Tenga en cuenta la carcasa de las palabras alTeR Table tempDB.dbo.MyALTERTest ... DATEcreated para comparar con lo que está en el XML.

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

debería ver lo siguiente en la pestaña "Mensajes" (comentarios agregados por mí):

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

Hubiera sido agradable si los datos por columnas (es decir NULL/NOT NULL, tipo de datos, etc.) se capturaron en lugar de solo el nombre, pero si es necesario, se pueden analizar a partir del 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; 
Cuestiones relacionadas