用一些初始值填充 schema_only table
Populate schema_only table with some initial values
是否可以在数据库启动时填充 schema_only table(带有一些初始值),例如通过调用存储过程?
如果我必须检测是否发生冷启动,通常在此 table 上运行的逻辑会更加复杂。
编辑:
似乎 sp_procoption
让我成功了一半。但是,这样配置的存储过程在ALTER DATABASE <dbname> SET ONLINE;
为运行时不执行。这是一个无赖,因为当 ALTER DATABASE <dbname> SET OFFLINE;
是 运行 时数据确实消失了。
您可以使用 DDL trigger for ALTER_DATABASE event type. The difficult part is to find when it's state is changed from OFFLINE to ONLINE (instead of some other ALTER DATABASE statement, like MODIFY FILE for example). When the trigger is fired, EVENTDATA() 函数检测 ALTER DATABASE <dbname> SET ONLINE;
语句 return 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 table 中是否有任何行。当然,在触发器中你还应该检查这个事件是否与你的数据库相关。所以触发器可能看起来像这样:
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
是否可以在数据库启动时填充 schema_only table(带有一些初始值),例如通过调用存储过程?
如果我必须检测是否发生冷启动,通常在此 table 上运行的逻辑会更加复杂。
编辑:
似乎 sp_procoption
让我成功了一半。但是,这样配置的存储过程在ALTER DATABASE <dbname> SET ONLINE;
为运行时不执行。这是一个无赖,因为当 ALTER DATABASE <dbname> SET OFFLINE;
是 运行 时数据确实消失了。
您可以使用 DDL trigger for ALTER_DATABASE event type. The difficult part is to find when it's state is changed from OFFLINE to ONLINE (instead of some other ALTER DATABASE statement, like MODIFY FILE for example). When the trigger is fired, EVENTDATA() 函数检测 ALTER DATABASE <dbname> SET ONLINE;
语句 return 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 table 中是否有任何行。当然,在触发器中你还应该检查这个事件是否与你的数据库相关。所以触发器可能看起来像这样:
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