查找表的列的创建日期/时间

Koe*_*box 8 sql t-sql sql-server sql-server-2005

如何查询SQL Server以获取SQL Server 2005表列的创建日期?

我试图sp_columns [tablename]获取该信息,但创建日期未包含在此存储过程中.

如何才能做到这一点?

Bea*_*692 8

这个名为sys.Columns的系统表可以从中获取列信息.如果要查看特定表的列,可以按如下方式执行:

SELECT col.* from sys.objects obj 
inner join sys.columns col 
on obj.object_Id=col.object_Id 
and obj.Name=@tableName
Run Code Online (Sandbox Code Playgroud)

或者你可以得到这样的表格信息:

SELECT * FROM sys.objects WHERE Name=@tableName
Run Code Online (Sandbox Code Playgroud)

但是我找不到关于列创建日期的任何信息.

更新: 可能会有所帮助.

  • +1 - 列创建日期似乎不可用,也不提供链接 (3认同)

Sol*_*zky 7

SQL Server不跟踪表的特定更改.如果您需要或需要此级别的详细信息,则需要创建可以捕获某些特定事件甚至事件类的DDL触发器(在SQL Server 2005中引入),并将这些更改记录到您创建的历史记录表中.

DDL触发器是"后"触发器; 没有"代替"选项.但是,如果您想要禁止某个操作,您只需发出一个操作即可ROLLBACK取消所发生的操作.

DDL触发器的MSDN页面有很多关于如何捕获特定事件(即ALTER TABLE)和使用EVENTDATA返回XML 的函数的信息,以获取触发触发器的事件的细节,包括执行的确切SQL查询.实际上,使用EVENTDATA函数的MSDN页面甚至包含创建DDL触发器以捕获ALTER TABLE语句的简单示例(在"ALTER TABLE和ALTER DATABASE事件"部分中)并创建DDL触发器以将事件捕获到日志表(在"示例"部分中).由于所有ALTER TABLE命令都会触发此触发器,因此您需要解析哪些命令特定于您要查找的内容.而且,现在您可能知道这是一个选项,需要捕获的不仅仅是添加列(即删除列,更改数据类型和/或可空性等).

应该注意,您可以ON ALL SERVER为数据库范围的事件创建DLL触发器,例如ALTER_TABLE.

如果要查看任何事件或事件类的XML结构,请转到:

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

并单击"当前版本:"链接.如果要查看特定事件或事件类,只需在触发器的"FOR"子句(包括下划线)中使用的事件名称上进行搜索(通常是浏览器中的Control-F).以下是该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>
Run Code Online (Sandbox Code Playgroud)

这是一个非常简单的测试,看看它是如何工作的以及产生的EventData XML的样子:

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
Run Code Online (Sandbox Code Playgroud)

首先,我们在tempdb中创建一个简单的实际表(不会为临时表捕获这些事件):

USE [tempdb];
CREATE TABLE dbo.MyAlterTest (Col2 INT NULL);
Run Code Online (Sandbox Code Playgroud)

接下来我们添加一列.我们从另一个数据库执行此操作,以确保XML捕获对象所在的数据库而不是当前数据库.请注意alTeR Table tempDB.dbo.MyALTERTest ... DATEcreated与XML中的内容进行比较的单词大小写.

USE [master];
alTeR Table tempDB.dbo.MyALTERTest ADD DATEcreated DATETIME NOT NULL;
Run Code Online (Sandbox Code Playgroud)

您应该在"消息"选项卡中看到以下内容(我添加的评论):

<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>
Run Code Online (Sandbox Code Playgroud)

如果捕获每列详细信息(即NULL/NOT NULL,数据类型等)而不仅仅是名称,那将是很好的,但如果需要,可以从CommandText元素中解析出来.