问题
We're using SQL Server 2000 Query Analyser, and one issue we have is that very occasionally, when a user is updating our live database, they insert the incorrect/no(!) where
clause. I know, not good, but it happens.
Are there any editors that will warn of the number of rows that might be changed (if that is even possible) or even a way to configure an editor, if it is connected to a certain database, to prompt for confirmation before the query is run?
We have a way to recover our data in the cases where we run an incorrect query, but it takes time, and I'm just seeing if there are any ways to catch the error, or at least give the user a second chance.
Thanks in advance.
回答1:
The only way is to not to let user edit data using SQL Server 2000 Query Analyser! But then you'll have to write an application and control the data, and you can then issue warnings as necessary.
Short of that, you could add triggers to every table and set some sort limit where you issue a ROLLBACK if the rows affected is greater than X. You could even use something like SUSER_NAME() to apply the limit to certain users.
sample trigger:
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
to automatically generate all the triggers scripts run this (does not actually add them in the database, just produce the text script which you should edit and then run):
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
all tables will have an affected row limit of 5 unless you login as user "AwesomeSA". The above script will generate the code, not actually create the triggers. You can edit the output of this script, setting good row limits, users, etc. and then run that script and then the triggers will be created.
回答2:
One approach is to create a template that wraps statements in a transaction, and rollback at the end. That way you can see affected rows and undo.
If you install the SQL Server Management Studio Tools Pack, then the default behaviour (configurable) when clicking on 'New Query...' is to open a window with
BEGIN TRAN
ROLLBACK
in it.
回答3:
To take Mitch Wheat's answer and expand I've used this with success. If I was going to use this regularly I'd make a stored procedure that would take the expected row count, from statement and where statement as input and automate the entire thing.
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
来源:https://stackoverflow.com/questions/2551510/sql-server-query-editors-any-that-warn-of-number-of-rows-to-be-changed