2

是否可以在数据库启动时填充 schema_only 表(带有一些初始值),例如通过调用存储过程?

如果我必须检测是否发生了冷启动,则通常在此表上运行的逻辑会更加复杂。

编辑:

似乎sp_procoption让我走到了一半。但是,这样配置的存储过程在运行时是不会执行ALTER DATABASE <dbname> SET ONLINE;的。这是一个遗憾,因为数据在ALTER DATABASE <dbname> SET OFFLINE;运行时确实会消失。

4

1 回答 1

4

您可以检测带有ALTER_DATABASE事件类型的DDL 触发器ALTER DATABASE <dbname> SET ONLINE;语句。困难的部分是找到它的状态何时从 OFFLINE 更改为 ONLINE(而不是其他一些 ALTER DATABASE 语句,例如 MODIFY FILE)。当触发器被触发时,EVENTDATA()函数将返回如下 XML:

<EVENT_INSTANCE>
  <EventType>ALTER_DATABASE</EventType>
  <PostTime>2018-12-17T16:26:25.250</PostTime>
  <SPID>80</SPID>
  <ServerName>xxxxxxx</ServerName>
  <LoginName>xxxxxxxxxxxxxxxxxx</LoginName>
  <DatabaseName>xxxxx</DatabaseName>
  <TSQLCommand>
    <SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" />
    <CommandText>ALTER DATABASE xxxxx SET OFFLINE</CommandText>
  </TSQLCommand>
</EVENT_INSTANCE>


<EVENT_INSTANCE>
  <EventType>ALTER_DATABASE</EventType>
  <PostTime>2018-12-17T16:26:36.953</PostTime>
  <SPID>80</SPID>
  <ServerName>xxxxxxx</ServerName>
  <LoginName>xxxxxxxxxxxxxxxxxx</LoginName>
  <DatabaseName>xxxxx</DatabaseName>
  <TSQLCommand>
    <SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" />
    <CommandText>ALTER DATABASE xxxxx SET ONLINE</CommandText>
  </TSQLCommand>
</EVENT_INSTANCE>

理论上你可以尝试解析<CommandText>,但它可能不像听起来那么容易。取而代之的是,您可以检查您的数据库当前是否在线以及 schema_only 表中是否有任何行。当然,在触发器中您还应该检查此事件是否与您的数据库相关。所以触发器可能看起来像这样:

CREATE TRIGGER DDL_ALTER_DATABASE_TRIGGER
ON ALL Server
FOR ALTER_DATABASE
AS
BEGIN
    declare @DatabaseName nvarchar(200), @TSQL nvarchar(2000), @event XML

    select @event = EVENTDATA()

    select @DatabaseName = @event.value('(/EVENT_INSTANCE/DatabaseName)[1]','varchar(200)' )
    select @TSQL = @event.value('(/EVENT_INSTANCE/TSQLCommand)[1]','varchar(2000)' ) -- Check the command text if you want

    if @DatabaseName = '<my database name>'
    begin
        declare @DatabaseCurrentState int

        select @DatabaseCurrentState = state
        from sys.databases
        where name = '<my database name>'

        if @DatabaseCurrentState = 0 -- It is ONLINE now
        begin
            if not exists(select * from [<my database name>].schema.schema_only_table)
            begin
                insert into [<my database name>].schema.schema_only_table(field1, field2)
                values(1, 2)
                -- or simply execute your auto executed stored procedure here
            end
        end
    end
END
于 2018-12-17T14:40:50.560 回答