SQL Server Query Editors - any that warn of number of rows to be changed?

雨燕双飞 提交于 2019-12-12 23:07:32

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!