是否可以在数据库启动时填充 schema_only 表(带有一些初始值),例如通过调用存储过程?
如果我必须检测是否发生了冷启动,则通常在此表上运行的逻辑会更加复杂。
编辑:
似乎sp_procoption
让我走到了一半。但是,这样配置的存储过程在运行时是不会执行ALTER DATABASE <dbname> SET ONLINE;
的。这是一个遗憾,因为数据在ALTER DATABASE <dbname> SET OFFLINE;
运行时确实会消失。
是否可以在数据库启动时填充 schema_only 表(带有一些初始值),例如通过调用存储过程?
如果我必须检测是否发生了冷启动,则通常在此表上运行的逻辑会更加复杂。
编辑:
似乎sp_procoption
让我走到了一半。但是,这样配置的存储过程在运行时是不会执行ALTER DATABASE <dbname> SET ONLINE;
的。这是一个遗憾,因为数据在ALTER DATABASE <dbname> SET OFFLINE;
运行时确实会消失。
您可以检测带有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