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