I ran an insert query on a table in SQL Server by mistake and 100 rows got inserted. I want to undo it but I do not have rollback.
You can only delete, but for future you would need to surround your query in transaction or set such behavior manually.
By default SSMS does auto-commit. To alter this behavior use this:
SET IMPLICIT_TRANSACTIONS OFF
more here:
https://learn.microsoft.com/en-us/sql/t-sql/statements/set-implicit-transactions-transact-sql?view=sql-server-ver15
Related
I am using the mssql-jdbc JDBC driver to do the following in a single transaction.
Executed the following statement:
delete from table1
There were around 10 records in the table which were deleted (execute update returned 10). Then, immediately following the delete, executed the following select statement:
select count(*) from table1
Resultset said that there are still 10 records.
In other DBs like Oracle and Postgres, we get 0, which is what I am expecting.
I do not want autocommit=true behaviour. Also, the two statements need to execute in the same transaction.
Is there anything I can do to get the behaviour I want?
Answering for my question.
There was a bug in the on-delete cascade trigger we had added for the table.
As a result, a commit was not happening when records in that table were deleted. Since no JDBC exceptions were being thrown for failures in the trigger, the problem was not apparent from Java end.
There was no other issue.
I have inherited an older system that has multiple programs using one SQL Server 2000 database. I can't change the software and one of the programs is randomly performing a destructive update that sets some columns to null.
The best solution I can come up with is to create an INSTEAD OF UPDATE trigger to validate the update and only allow it if does not contain a null value. I can't count on the SQL command being done in a transaction that I can roll back using an AFTER trigger. Proper parameterized SQL is being used.
What we can't figure out is:
How to check the value of a #parameter here, and
If it's ok, allow the original SQL command to execute.
Appreciate any ideas!
CREATE TRIGGER [dbo].[trd_tablename]
ON [dbo].[tablename]
INSTEAD OF UPDATE
AS
BEGIN
IF #parameter IS NOT NULL
--run the original statement
END
I can't work out why this is the case, but if I run:
BEGIN TRANSACTION
ALTER TABLE [TABLE NAME] DISABLE TRIGGER [TRIGGER NAME];
-- Some query
ALTER TABLE [TABLE NAME] ENABLE TRIGGER [TRIGGER NAME];
COMMIT TRANSACTION
Where 'some query' depends on the trigger being disabled, I get an error (since the trigger hasn't successfully been disabled).
However, if I run the alter statements separately, it's fine.
I've tried DISABLE TRIGGER syntax instead, and I've tried BEGIN and END instead of BEGIN TRANSACTIONetc.
What am I misunderstanding here? Why do these alter statements not appear to alter 'in time'?
EDIT
I'd like to rephrase the question in favour of clarity to accompany the bounty:
Why must we separate batches of DDL and DML?
Since you are executing them in the same batch/statement, you are altering table AFTER sql server has compiled your sql statement.
SQL Server compiles your statement (including all the individual DDL
and DML commands in the batch)
SQL Server alters your TABLE to disable trigger
SQL Server runs your "query", but it is compiled to assume there was
a trigger there, so the trigger runs.
SQL Server alters your TABLE to enable trigger
To solve this, you can still do it within a transaction, but you will need to separate into batches. Insert "GO" between each statement if running from SSMS or similar tool, or call individual SQL statement if calling from code.
Mixing DDL and DML in transactions is not advised as it can produce undesired results:
ALTER TABLE [TABLE NAME] DISABLE TRIGGER [TRIGGER NAME];
BEGIN TRANSACTION
-- Some query
COMMIT TRANSACTION
ALTER TABLE [TABLE NAME] ENABLE TRIGGER [TRIGGER NAME];
People,
I need migrate a Oracle trigger to SQL server, but I could not do.
The trigger in Oracle is very simple:
CREATE OR REPLACE TRIGGER trigger_teste
BEFORE INSERT OR UPDATE
ON teste
FOR EACH ROW
DECLARE
BEGIN
:new.id := (coalesce(:NEW.id, 0));
:new.vlr_sal := (coalesce(:NEW.vlr_sal, 0.00));
END;
I tried several ways but none successfully!
Thank for help!
My T-SQL is a bit rusty, but something like this should work. Note that SQL server does not have row level triggers, only statement level triggers.
CREATE TRIGGER trigger_teste
ON teste
BEFORE INSERT OR UPDATE
AS
update inserted
set id = coalesce(id, 0),
vlr_sal = coalesce(vlr_sal, 0.0)
GO
(Not sure if I got missed a semicolon or not. I never understood when SQL Server needs or deosn't need one)
See the manual for more details:
http://msdn.microsoft.com/en-US/library/ms189799%28v=sql.90%29
http://msdn.microsoft.com/en-US/library/ms191300%28v=sql.90%29
This is not an appropriate use of triggers in any flavour of RDBMS. The SQL standard allows us to define default values when we create the table using the DEFAULT constraint syntax. Both Oracle and SQL Server have this.
Obviously you haven't do this when you created the table. The good news is we can use ALTER TABLE to add default constraints. Something like this
alter table teste
alter column id set default 0
That's for SQL Server. In Oracle it would be:
alter table teste
modify id default 0
As the nameless equine points out, a complete replacement for the trigger must include NOT NULL constraints on the affected columns. If the existing table lacks not null constraints we can add them using the same syntax as shown above, replacing the DEFAULT clause with NOT NULL - or even combining the two clauses in the same statement.
I need to alter a trigger in SQL Server. After I am doing, do I just execute the trigger similar to how I would do for a Stored Procedure?
ALTER TRIGGER
Yes, that is right, just use ALTER. If you right-click on your trigger in Object Explorer in SSMS and select Script Trigger as/ALTER To, you will see the ALTER statement created for your trigger.
ALTER TRIGGER triggerName
ON tableName
FOR INSERT -- or update & delete
AS
-- sql here
http://msdn.microsoft.com/en-us/library/ms176072.aspx
You don't "execute" a trigger. Triggers are "triggered" at certain points depending upon your definition of them.
For example an AFTER UPDATE trigger would run for all rows updated after you send an UPDATE command to the table on which the trigger is created.