我们正在使用 SQL Server 2000 查询分析器,我们遇到的一个问题是,当用户更新我们的实时数据库时,他们偶尔会插入不正确的/no(!)where
子句。我知道,不好,但它发生了。
是否有任何编辑器会警告可能更改的行数(如果可能的话),甚至是配置编辑器的方法,如果它连接到某个数据库,则在运行查询之前提示确认?
在我们运行错误查询的情况下,我们有办法恢复我们的数据,但这需要时间,我只是看看是否有任何方法可以捕获错误,或者至少给用户第二次机会。
提前致谢。
我们正在使用 SQL Server 2000 查询分析器,我们遇到的一个问题是,当用户更新我们的实时数据库时,他们偶尔会插入不正确的/no(!)where
子句。我知道,不好,但它发生了。
是否有任何编辑器会警告可能更改的行数(如果可能的话),甚至是配置编辑器的方法,如果它连接到某个数据库,则在运行查询之前提示确认?
在我们运行错误查询的情况下,我们有办法恢复我们的数据,但这需要时间,我只是看看是否有任何方法可以捕获错误,或者至少给用户第二次机会。
提前致谢。
唯一的办法是不要让用户使用 SQL Server 2000 查询分析器编辑数据! 但是您必须编写一个应用程序并控制数据,然后您可以根据需要发出警告。
除此之外,您可以向每个表添加触发器并设置某种排序限制,如果受影响的行大于 X,则在其中发出 ROLLBACK。您甚至可以使用SUSER_NAME()之类的东西将限制应用于某些用户。
示例触发器:
CREATE TRIGGER Trigger_YourTable ON YourTable
FOR INSERT, UPDATE, DELETE
AS
DECLARE @Limit int
DECLARE @Message varchar(100)
SET @Limit=5
SET @Message='ERROR, Not Permitted to alter more than '+CONVERT(varchar(5),@Limit)+' rows at any one time.'
IF SUSER_NAME() !='AwesomeSA'
BEGIN
IF @Limit<(SELECT COUNT(*) FROM INSERTED)
BEGIN
ROLLBACK
RAISERROR(@Message, 16, 1);
RETURN
END
ELSE IF @Limit<(SELECT COUNT(*) FROM DELETED)
BEGIN
ROLLBACK
RAISERROR(@Message, 16, 1);
RETURN
END
END
GO
自动生成所有触发器脚本运行这个(实际上并不将它们添加到数据库中,只需生成您应该编辑然后运行的文本脚本):
DECLARE @SQL varchar(8000)
SET @SQL='PRINT ''CREATE TRIGGER [''+REPLACE(REPLACE(REPLACE(''Trigger_?'',''['',''''),'']'',''''),''.'',''_'')+''] ON ?''; PRINT ''FOR INSERT, UPDATE, DELETE
AS
DECLARE @Limit int
DECLARE @Message varchar(50)
SET @Limit=5
SET @Message=''''ERROR, Not Permitted to alter more than ''''+CONVERT(varchar(5),@Limit)+'''' rows at any one time.''''
IF SUSER_NAME() !=''''AwesomeSA''''
BEGIN
IF @Limit<(SELECT COUNT(*) FROM INSERTED)
BEGIN
ROLLBACK
RAISERROR(@Message, 16, 1);
RETURN
END
ELSE IF @Limit<(SELECT COUNT(*) FROM DELETED)
BEGIN
ROLLBACK
RAISERROR(@Message, 16, 1);
RETURN
END
END
GO'''
EXEC sp_msforeachtable @SQL
除非您以用户“AwesomeSA”身份登录,否则所有表的受影响行数限制为 5。上面的脚本将生成代码,而不是实际创建触发器。您可以编辑此脚本的输出,设置好的行限制、用户等,然后运行该脚本,然后将创建触发器。
一种方法是创建一个模板,将语句包装在事务中,并在最后回滚。这样您就可以看到受影响的行并撤消。
如果您安装SQL Server Management Studio Tools Pack,则单击“新查询...”时的默认行为(可配置)是打开一个窗口
BEGIN TRAN
ROLLBACK
在里面。
为了接受 Mitch Wheat 的回答并扩展,我已经成功地使用了它。如果我要定期使用它,我会创建一个存储过程,它将预期的行数、from 语句和 where 语句作为输入并自动化整个事情。
begin tran
declare @err int
declare @cnt int
-- select total count of records to be deleted
select @cnt = count(*)
from dbo.table
where delete_ind = 1
-- show that in the results pane
select 'Count', @cnt
-- Delete it (note that the from and where statements are the same from count query)
Delete
from dbo.table
where delete_ind = 1
select @err = @@error
if @err <> 0 --check to see if query failed
BEGIN
-- Return 99 to the calling program to indicate failure.
raiserror('An error occurred deleting from dbo.table.',16,1)
ROLLBACK
END
ELSE if @cnt = 1168730 --yes this is a hard coded expected row count
BEGIN
raiserror('Delete processed %i rows from dbo.table.',1,1,@cnt)
COMMIT
END