Problem to drop a table because of tr_MStran_droptable - sql-server

I have several databases with similar structures on several servers. I have a job who drop a table and recreate it in the night for every database. But I had a problem with only one database on one server :
Invalid value given for parameter #procmapid. Specify a valid
parameter value.
I made some research and I have seen that the problem was because the trigger tr_MStran_droptable was enabled. So I disable it and now it works. But on my other database this trigger is enabled too and I can drop the table.
How it is possible? I can't find this trigger structure to study it in the database too. Did somebody know more about the trigger tr_MStran_droptable?
Trigger code :
CREATE TRIGGER [tr_MStran_droptable] ON DATABASE
FOR DROP_TABLE AS
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
SET ARITHABORT ON
SET CONCAT_NULL_YIELDS_NULL ON
SET NUMERIC_ROUNDABORT OFF
SET QUOTED_IDENTIFIER ON
DECLARE #EventData XML
SET #EventData = EventData()
IF object_id('dbo.sysarticles') IS NULL
OR object_id('dbo.syspublications') IS NULL
OR object_id('dbo.sysextendedarticlesview') IS NULL
OR EXISTS (
SELECT 1
FROM #EventData.nodes('/EVENT_INSTANCE') AS R(event_instance)
WHERE lower(event_instance.value('SchemaName[1]', 'sysname')) IN (
N'sys'
,N'cdc'
)
OR lower(event_instance.value('ObjectName[1]', 'sysname')) IN (
N'sysextendedarticlesview'
,N'sysarticles'
,N'syspublications'
)
OR event_instance.value('ObjectName[1]', 'sysname') LIKE N'#%'
)
RETURN
EXEC sys.sp_MStran_ddlrepl #EventData
,5
GO
DISABLE TRIGGER [tr_MStran_droptable] ON DATABASE
GO

It's Because of the trigger :
The trigger is to keep replication alive so :
Try running sp_removedbreplication 'CurrentDatabase' that will remove replication
or
Disable Trigger : DISABLE TRIGGER [tr_MStran_droptable] ON DATABASE

Related

With a DACPAC, how can I rename a column when there is a trigger on the table?

I'm trying to rename columns in a table for which there is a trigger. I've used SQL > Refactor > Rename to rename the column. And the trigger file also gets updated. However, when I publish, I get this:
Procedure TR_accrual_Accrual_Update, Line 134 Invalid column name
'MinHoursRule'.
That's the old column name. I'm assuming the publish is updating the table first, and sees that the current/old trigger still has the old column name.
Is it possible to rename a column, update the trigger, and publish?
The only solution I can really think of is to do this:
Delete the triggers and publish
Rename the columns
Add the triggers again
Publish
This is what I did as a work-around:
Add the new columns
Leave the old columns
Have the trigger use both sets of columns
Publish/deploy to prod soon
Remove the old columns
Publish/deploy to prod later
So, instead of renaming, I just created new columns, and then eventually deleted the old ones.
Yuck. But it worked.
Note: In our C# domain models, I only reference the new columns.
I guess that you have something wrong with the publish profile settings. You might have something disabled, for example "Do not modify triggers" or something like that. I just created new SSDT project in VS 2019 with following structure:
CREATE TABLE [dbo].[test]
(
[Id] INT ,
b int
)
GO
CREATE TRIGGER [dbo].[Trigger_test]
ON [dbo].[test]
FOR DELETE, INSERT, UPDATE
AS
BEGIN
SET NoCount ON
insert into test2 select b from inserted
END
GO
CREATE TABLE [dbo].[test2]
(
a int
)
GO
Published the project with default settings to the new database and made single insert to the dbo.test table. Made sure that there is record in dbo.test2 table. After that I re-factored dbo.test.b column to dbo.test.a then published again and everything worked. This is generated script:
/*
Deployment script for trg_test
This code was generated by a tool.
Changes to this file may cause incorrect behavior and will be lost if
the code is regenerated.
*/
GO
SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER ON;
SET NUMERIC_ROUNDABORT OFF;
GO
:setvar DatabaseName "trg_test"
:setvar DefaultFilePrefix "trg_test"
:setvar DefaultDataPath ""
:setvar DefaultLogPath ""
GO
:on error exit
GO
/*
Detect SQLCMD mode and disable script execution if SQLCMD mode is not supported.
To re-enable the script after enabling SQLCMD mode, execute the following:
SET NOEXEC OFF;
*/
:setvar __IsSqlCmdEnabled "True"
GO
IF N'$(__IsSqlCmdEnabled)' NOT LIKE N'True'
BEGIN
PRINT N'SQLCMD mode must be enabled to successfully execute this script.';
SET NOEXEC ON;
END
GO
USE [$(DatabaseName)];
GO
PRINT N'The following operation was generated from a refactoring log file 80d0e5de-e188-465e-b83c-18f38a1cec98';
PRINT N'Rename [dbo].[test].[b] to a';
GO
EXECUTE sp_rename #objname = N'[dbo].[test].[b]', #newname = N'a', #objtype = N'COLUMN';
GO
PRINT N'Altering Trigger [dbo].[Trigger_test]...';
GO
ALTER TRIGGER [dbo].[Trigger_test]
ON [dbo].[test]
FOR DELETE, INSERT, UPDATE
AS
BEGIN
SET NoCount ON
insert into test2 select a from inserted
END
GO
-- Refactoring step to update target server with deployed transaction logs
IF OBJECT_ID(N'dbo.__RefactorLog') IS NULL
BEGIN
CREATE TABLE [dbo].[__RefactorLog] (OperationKey UNIQUEIDENTIFIER NOT NULL PRIMARY KEY)
EXEC sp_addextendedproperty N'microsoft_database_tools_support', N'refactoring log', N'schema', N'dbo', N'table', N'__RefactorLog'
END
GO
IF NOT EXISTS (SELECT OperationKey FROM [dbo].[__RefactorLog] WHERE OperationKey = '80d0e5de-e188-465e-b83c-18f38a1cec98')
INSERT INTO [dbo].[__RefactorLog] (OperationKey) values ('80d0e5de-e188-465e-b83c-18f38a1cec98')
GO
GO
PRINT N'Update complete.';
GO

Cannot drop/alter tables due to transaction ended in trigger error ms-sql-server 2008

I cannot alter/drop any objects in my database, only create, insert, and delete records. For instance, I'm getting...
You can not
Msg 3609, Level 16, State 2, Line 1
The transaction ended in the trigger. The batch has been aborted.
on the following code (on the drop table step):
create schema Test
go
create table test.test (
test varchar(5)
)
go
insert into test.test(test) values('test')
go
select *
from Test.test
go
drop table Test.test
go
drop schema Test
go
I have definitely not created any triggers on the database EVER. I do not have control of the server so my permissions are limited. The problem just occurred. I have been using this database for years. This is the first time this has happened. I believe it has something to do with permissions.
I have no idea what is causing this new error to occur.
I found the problem. Someone hacked my database by adding a database trigger "test_ddl_trigger":
`SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create trigger [test_ddl_trigger] on database for drop_table, alter_table as print 'You can not'
rollback
;
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
ENABLE TRIGGER [test_ddl_trigger] ON DATABASE
GO`

QUOTED IDENTIFIER error in SQL Server 2008 on SP execution

I have this error on executing stored procedure:
INSERT failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.
Procedure is created with QUOTED_IDENTIFIER flag set to ON
IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'sp_procedure') AND TYPE IN (N'P', N'PC'))
BEGIN
DROP PROCEDURE [dbo].[sp_procedure]
END
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[sp_procedure]
(
#param_1 XML
,#param_2 INT
)
AS
BEGIN
-- CODE
END
SELECT statement from sys.sql_modules shows that uses_quoted_identifiers somehow is set to 0.
I have already tried to execute following code. It run in one batch.
SET QUOTED_IDENTIFIER ON;
EXEC sp_procedure #param_1 = N'<?xml version="1.0" encoding="utf-16"?>
xmlns:xsd="http://www.w3.org/2001/XMLSchema" />', #param_2= 51326
But it does not help.
Each session is created with QUOTED_IDENTIFIER set to 1:
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
Any ideas what can it be?
UPD
Turned out that after running this specific script, there also run lots of other files. And one of them just recreated stored procedure with QUOTED_IDENTIFIER set to OFF.
Thank you for your help
Pleasure make sure the table and view definitions are also created with quoted identifier on.

SQL SERVER 2008 TRIGGER ON CREATE TABLE

Is there a way to run some function like a trigger when a table is created in the database in SQL SERVER 2008?
Yes, it's called a DDL trigger. The documentation for CREATE TRIGGER has a sample for DROP_SYNONYM (a very questionable choice for an example) but you'll want the CREATE_TABLE event instead. A better starting point in understanding how they work is probably here:
http://msdn.microsoft.com/en-us/library/ms190989.aspx
If you have more specific details, e.g. what exactly do you want to pass to this function (I assume you mean procedure), or what does the procedure do, we can provide more useful and specific help.
Yes a DDL Trigger. For example, here is some code I written to prevent some tables from being modified:
PRINT N'Create DDL trigger to prevent changes to various tables'
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER NoEditCertainTables ON DATABASE
FOR DROP_TABLE, ALTER_TABLE, CREATE_TABLE
AS
SET CONCAT_NULL_YIELDS_NULL ON
DECLARE #AffectedTable varchar(255)
SELECT #AffectedTable = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(100)')
--This is the name of the table(s) you dont want messed with
IF (#AffectedTable IN ('Table1','Table2','Table3'))
BEGIN
ROLLBACK;
END
SET CONCAT_NULL_YIELDS_NULL OFF
GO

SQL Server ANSI_Padding

If I right click on a table in SQL Server Management Studio and select 'Script table as > Create to > New Query Editor Window' the code that appears contains:
SET ANSI_PADDING ON
.... create the table ...
SET ANSI_PADDING OFF
So, I guess, whether ANSI_Padding is on or off affects the whole database and it is turned on to create a table and then turned off again?
What happens if you create a table with ANSI_Padding off? How can you turn it on for that table?
SET ANSI_PADDING Controls the way
the column stores values shorter than
the defined size of the column, and
the way the column stores values that
have trailing blanks in char, varchar,
binary, and varbinary data.
In a future version of MicrosoftSQL Server ANSI_PADDING will
always be ON and any applications that
explicitly set the option to OFF will
produce an error. Avoid using this
feature in new development work, and
plan to modify applications that
currently use this feature.
This setting affects only the definition of new columns. After the column is created, SQL Server stores the values based on the setting when the column was created. Existing columns are not affected by a later change to this setting.
So, I guess, whether ANSI_Padding is on or off affects the whole database and it is turned on to create a table and then turned off again?
no, the SET option only affects the context of your connection, if 2 connections come in and one has ANSI_PADDING OFF and the other one ON they don't affect the other connection. However....the table created in one connection will have the behavior that the setting did to it.
read more here http://msdn.microsoft.com/en-us/library/ms190356.aspx
So if connection 1 comes in with set ansi_nulls off
then select * from bla where col = null will work
this however won't work for connection 2 if it comes with with the default ansi_nulls setting (ON)
you can see what you settings are by either executing dbcc useroptions or if you are on 2005 and up
SELECT SPID,VALUE,ANSI_SETTING
FROM (
SELECT ##SPID AS SPID,
CASE quoted_identifier
WHEN 1 THEN 'SET' ELSE 'OFF' END QUOTED_IDENTIFIER,
CASE arithabort
WHEN 1 THEN 'SET' ELSE 'OFF' END ARITHABORT,
CASE ansi_null_dflt_on
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_NULL_DFLT_ON,
CASE ansi_defaults
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_DEFAULTS ,
CASE ansi_warnings
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_WARNINGS,
CASE ansi_padding
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_PADDING,
CASE ansi_nulls
WHEN 1 THEN 'SET' ELSE 'OFF' END ANSI_NULLS,
CASE concat_null_yields_null
WHEN 1 THEN 'SET' ELSE 'OFF' END CONCAT_NULL_YIELDS_NULL
FROM sys.dm_exec_sessions
WHERE session_id = ##SPID ) P
UNPIVOT (VALUE FOR ANSI_SETTING IN(
QUOTED_IDENTIFIER,ARITHABORT,ANSI_NULL_DFLT_ON,
ANSI_DEFAULTS,ANSI_WARNINGS,
ANSI_PADDING,ANSI_NULLS,CONCAT_NULL_YIELDS_NULL
)
) AS unpvt

Resources