用一些初始值填充schema_only表

时间:2018-12-13 18:48:08

标签: sql-server memory-optimized-tables

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

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

编辑:

似乎sp_procoption让我走了一半。但是,运行ALTER DATABASE <dbname> SET ONLINE;时不会执行这种方式配置的存储过程。真是令人讨厌,因为运行ALTER DATABASE <dbname> SET OFFLINE;时数据确实消失了。

1 个答案:

答案 0 :(得分:4)

对于DDL trigger事件类型,您可以使用ALTER_DATABASE检测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>,但是它可能听起来并不容易。取而代之的是,您可以检查数据库当前是否为ONLINE,并且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