.Net 6 Error on creation of TSQL trigger in Migration - tsql

Has anyone got a clue on how to address the following issue?
When attempting to update a database via migration I get the following error:
An explicit value for the identity column in table 'HistoryUsers' can only be specified when a column list is used and IDENTITY_INSERT is ON.
Running the trigger in Management studio works!
The code giving the error:
migrationBuilder.Sql(#"
CREATE TRIGGER [Users_TRIGGER]
ON [Users]
AFTER UPDATE, INSERT, DELETE
AS
DECLARE #EmpID int, #user nvarchar(max), #activity nvarchar(200);
IF EXISTS(SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
BEGIN
SET #activity = 'UPDATE';
SET #user = SYSTEM_USER;
INSERT INTO [HistoryUsers]
SELECT *, #activity, CURRENT_TIMESTAMP, #user
FROM inserted
END
IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS(SELECT * FROM deleted)
BEGIN
SET #activity = 'INSERT';
SET #user = SYSTEM_USER;
INSERT INTO [HistoryUsers]
SELECT *, #activity, CURRENT_TIMESTAMP, #user
FROM inserted
END
IF EXISTS(SELECT * FROM deleted) AND NOT EXISTS(SELECT * FROM inserted)
BEGIN
SET #activity = 'DELETE';
SET #user = SYSTEM_USER;
INSERT INTO [HistoryUsers]
SELECT *, #activity, CURRENT_TIMESTAMP, #user
FROM deleted
END
GO
");

Related

PostgreSQL insert current sequence value to another field with condition

the issue:
i need to do something like this
drop table if exists tt_t;
create temp table tt_t(id serial primary key, main_id int, external_id int);
insert into tt_t(main_id, external_id)
select currval(pg_get_serial_sequence('tt_t', 'id')), 1
where not exists (select from tt_t where external_id = 1);
but execution raises an error
SQL Error [55000]: ERROR: currval of sequence "tt_t_id_seq" is not yet defined in this session
solution:
there is a way to solve this with anonymous code block
do
$$
begin
if not exists(select from tt_t where external_id = 1)
then
insert into tt_t(external_id, main_id)
values(1, currval(pg_get_serial_sequence('tt_t', 'id')));
end if;
end;
$$
;
but anonymous blocks has some restrictions e.g. Dapper parameters not working with PostgreSQL through npgsql connection, is postgres anonymous function parameterization supported?
how do i fix it without anonymous code block (UPD: and without any DDL changes)?
probable solution:
insert into tt_t(id, main_id, external_id)
select nextval(pg_get_serial_sequence('tt_t', 'id')), currval(pg_get_serial_sequence('tt_t', 'id')), 1
where not exists (select from tt_t where external_id = 1);
shorter code has been proposed to me
insert into tt_t(id, main_id, external_id)
select nextval(pg_get_serial_sequence('tt_t', 'id')), lastval(), 1
where not exists (select from tt_t where external_id = 1);
but i'm not sure if nextval will be calculated first
What about using a default value:
drop table if exists tt_t;
create temp table tt_t(id serial primary key, main_id int default lastval(), external_id int);
insert into tt_t(external_id)
select 1
where not exists (select * from tt_t where external_id = 1);
In theory it shouldn't be possible that another nextval() is called between the one for the id and the lastval(). However I am not 100% sure if there are some corner cases that I don't know of.
The following works as well (even if one or more of the external_id values already exist).
insert into tt_t(external_id)
select *
from (values (1),(2),(3)) x (external_id)
where not exists (select *
from tt_t
where external_id = x.external_id);

Trigger not saving historicals

Version: SQL Server 2008 R2
This trigger checks primary key violations, if any moves the row to the history table; and then deletes the row; and then inserts the row that caused the violation.
But it is not doing its job.
CREATE TRIGGER [dbo].[ONINSERT]
ON [dbo].[TICKETS]
Instead of INSERT
AS
BEGIN
DECLARE #ID VARCHAR(200)
SET NOCOUNT ON;
SET #ID = (SELECT TICKET_ID FROM inserted)
INSERT TICKET_HISTORY
SELECT * FROM TICKETS
WHERE
TICKET_ID = #ID ;
print 'Inserting ' + #id
DELETE FROM TICKETS
WHERE TICKET_ID = #ID;
print 'Deleting' + #id
INSERT TICKETS
SELECT * FROM inserted;
print 'Inserting back' + #id
Triggers fire only once even if you have multiple inserts,so in your case I don't see that happening...You don't need to delete the row again since instead of insert generally means "instead of insert do some custom action"
if exists
(
select 1 from inserted i
join
mytable t
on t.id=i.id
)
begin
--insert into tickets history
insert into ticketshistory
select i.* from inserted i
join
mytable t where t.id=i.id
---you can add custom logic to alert or simply ignore
return
end
--this is needed since if there is no violation you have to insert rows
insert into tickets
select * from inserted

EF5 "the selected stored procedure or function returns no columns"

I am using EF 5 and this is my SP
USE [MYDatabase] GO
SET ANSI_NULLS ON GO
SET QUOTED_IDENTIFIER ON GO
ALTER PROCEDURE [dbo].[SP_FirstAttend] #serviceStart date, #serviceEnd date AS
BEGIN
SET NOCOUNT OFF
SET FMTONLY OFF
--IF (1=0)
--BEGIN
--SET FMTONLY ON
BEGIN
DROP TABLE #temp1
CREATE TABLE #temp1 (id int, sid int, npi int, fiscal int, serviceStart date, serviceEnd date, fcode varchar(10), tid int, StudName varchar(200), TherName varchar (200))
INSERT INTO #temp1
SELECT ID,
mand.SID,
mand.NPI,
FiscalYear,
ServiceStart,
ServiceEnd,
FundingCode,
ther.TID,
RTRIM(stud.StudentLastName) + ' ' + RTRIM(stud.StudentFirstName),
RTRIM(ther.LastName) + ' ' + RTRIM(ther.FirstName)
FROM MandateMaster AS mand
JOIN TherapistMaster AS ther ON ther.NPI = mand.NPI
JOIN StudentMaster AS stud ON stud.SID = mand.SID
SELECT *,
(SELECT top(1) sid
FROM SessionDetail
WHERE SID = tb1.sid
AND TID = tb1.tid) AS val1
FROM #temp1 AS tb1
WHERE ServiceStart >= #serviceStart
AND ServiceStart <= #serviceEnd;
END
-- END
END
and its still giving me "Stored procedure returns no columns".
I read somewhere to set the
integrated security=True; in the connection string on web.config but still nothing worked.
I been trying to find the solutions for this but keep getting the same message. Please let me know what to do .
Thanks.
You got nothing as result because this condition IF (1=0) always returns false then your select statement is never hit.
Just remove this IF (1=0) and your stored procedure will return some data.

INSERT query from trigger inserts NULL

I have the following query in SQL Server 2005:
DECLARE #issueid numeric(10,0)
DECLARE #domain nvarchar (255)
SET #issueid = (SELECT issueid FROM issues WHERE issueid = 4850)
SET #domain = (SELECT fielddata FROM customfielddata WHERE issueid = #issueid AND customfieldid = 99)
PRINT CONVERT(NVARCHAR, #issueid) + ': ' + #domain
It outputs the result as expected:
4850: www.domain.com
When I have the same query in a trigger, it inserts the #issueid value correctly in the first column, but NULL in place of #section_name in the 2nd column:
CREATE TRIGGER trigger_website_sections
ON gemini_issues
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
IF (SELECT issuetypeid FROM inserted) = 58 BEGIN
DECLARE #issueid numeric(10,0)
DECLARE #domain nvarchar (255)
SET #issueid = (SELECT issueid FROM inserted)
SET #domain = (SELECT fielddata FROM customfielddata WHERE issueid = #issueid AND customfieldid = 99)
INSERT INTO website_sections VALUES (#issueid, #domain);
END
END
Can someone help figure out why?
Ok, after some more work I realised that because the row in customfielddata is created only after a row is created in issues (the 2nd is the primary table, and the 1st stores supplementary data for created records), the query on customfielddata will return NULL.
And trying to concatenate a string with a NULL returns a NULL and that's what's inserted into the row.
Mystery solved.

Why does this TSQL fail?

IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
BEGIN
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_Templates
(
ID int NOT NULL IDENTITY (1, 1),
isHidden bit NULL,
FileName nvarchar(255) NOT NULL,
Name nvarchar(255) NOT NULL,
Description nvarchar(1024) NULL,
UploadedByTVDBUsersID int NOT NULL,
Created datetime NOT NULL
)
GO
SET IDENTITY_INSERT dbo.Tmp_Templates ON
GO
IF EXISTS(SELECT * FROM dbo.Templates)
EXEC('INSERT INTO dbo.Tmp_Templates (ID, FileName, Name, Description, UploadedByTVDBUsersID, Created)
SELECT ID, FileName, Name, Description, UploadedByTVDBUsersID, Created FROM dbo.Templates WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_Templates OFF
GO
DROP TABLE dbo.Templates
GO
EXECUTE sp_rename N'dbo.Tmp_Templates', N'Templates', 'OBJECT'
GO
ALTER TABLE dbo.Templates ADD CONSTRAINT
PK__Templates__499219E9 PRIMARY KEY CLUSTERED
(
ID
)
GO
PRINT N' Templates ADD isHidden'
COMMIT
END
Results in error:
Msg 102, Level 15, State 1, Line 7 Incorrect syntax near
'TRANSACTION'. Caution: Changing any part of an object name could
break scripts and stored procedures.
Update:
Excluding the IF statement wrapping the transaction this SQL is generated by Microsoft SQL Server Management Studio.
If I remove the wrapping IF statement then everything works, but I only need the change to happen if the field isn't already there. How can I make the IF statement work properly?
Um... why the -1 and the vote to close?
I had to wrap each part of the transaction in an IF statement so the GOs were not embedded in an IF statement. The following TSQL works just fine. The transaction updates the schema as expected.
BEGIN TRANSACTION
GO
IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
BEGIN
CREATE TABLE dbo.Tmp_Templates
(
ID int NOT NULL IDENTITY (1, 1),
isHidden bit NULL,
FileName nvarchar(255) NOT NULL,
Name nvarchar(255) NOT NULL,
Description nvarchar(1024) NULL,
UploadedByTVDBUsersID int NOT NULL,
Created datetime NOT NULL
)
ALTER TABLE dbo.Tmp_Templates ADD PRIMARY KEY (ID)
END
GO
IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
BEGIN
SET IDENTITY_INSERT dbo.Tmp_Templates ON
END
GO
IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
BEGIN
IF EXISTS(SELECT * FROM dbo.Templates)
EXEC('INSERT INTO dbo.Tmp_Templates (ID, FileName, Name, Description, UploadedByTVDBUsersID, Created)
SELECT ID, FileName, Name, Description, UploadedByTVDBUsersID, Created FROM dbo.Templates WITH (HOLDLOCK TABLOCKX)')
END
GO
IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
BEGIN
SET IDENTITY_INSERT dbo.Tmp_Templates OFF
END
GO
IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
BEGIN
DROP TABLE dbo.Templates
END
GO
IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
BEGIN
EXECUTE sp_rename N'dbo.Tmp_Templates', N'Templates', 'OBJECT'
PRINT N' Templates ADD isHidden'
END
GO
COMMIT
first GO statement split your query to
IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
BEGIN
BEGIN TRANSACTION
//error - END missing
And there is BEGIN keyword without END.
You need to remove GO statement.
UPDATE:
IF 1 = 1
BEGIN
SELECT * FROM someTable
GO
END
also generate Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'someTable'.
SqlServer won't allow you to use sp_rename inside the transaction since it could break things badly.
You can drop and add the table again, on in your case, you can also use a temporale table to do the query work, truncate the old table, and move rows from temp into Templates.
Sample temp table
CREATE TABLE #myTempTable
(
DummyField1 INT,
DummyField2 VARCHAR(20)
)
Reference
http://msdn.microsoft.com/en-us/library/ms188351.aspx