Error in Insert into database in Stored Procedure - sql-server

I have a problem with this code :
ALTER PROCEDURE [arch].[spInsertToDocumentFileCategoryRelation]
#DocumentNumber nvarchar(50)
,#DocumentDate date
,#IsDocumentDelete bit
,#Address nvarchar(max)
,#DocumentLevelTypeId int
,#DocumentId2 bigint
,#DocumentRelationTypeId tinyint
,#CategoryId bigint
,#FileId bigint
,#FileAssignCategoryId bigint OUTPUT
,#DocumentRelationId bigint OUTPUT
,#FileOfDocumentId bigint OUTPUT
,#DocumentId bigint OUTPUT
AS
BEGIN
INSERT INTO [arch].[Document]
(
[DocumentNumber]
,[DocumentDate]
,[DateOfDocumentCreate]
,[IsDocumentDelete]
,[Address]
,[DocumentLevelTypeId]
)
VALUES
(
#DocumentNumber
,#DocumentDate
,'2015-5-12'
,#IsDocumentDelete
,#Address
,#DocumentLevelTypeId
)
Set #DocumentId = SCOPE_IDENTITY();
INSERT INTO [arch].[FileOfDocument]
(
[DocumentId]
,[FileId]
)
VALUES
(
#DocumentId
,#FileId
)
Set #FileOFDocumentId = SCOPE_IDENTITY();
INSERT INTO [arch].[DocumentRelation]
(
[DocumentRelationTypeId]
,[DocumentId1]
,[DocumentId2]
)
VALUES
(
#DocumentRelationTypeId
,#DocumentId
,#DocumentId2
)
Set #DocumentRelationId = SCOPE_IDENTITY();
INSERT INTO [arch].[FileAssignCategory]
(
[CategoryId]
,[FileId]
)
VALUES
(
#CategoryId
,#FileId
)
Set #FileAssignCategoryId = SCOPE_IDENTITY();
END
this code Execute correctly but when I want to test this Stored Procedure with some input values, sql server report some errors :
Msg 515, Level 16, State 2, Procedure
spInsertToDocumentFileCategoryRelation, Line 27
Cannot insert the value NULL into column 'DocumentTypeId', table
'ffisherDB.arch.Document'; column does not allow nulls. INSERT fails.
The statement has been terminated.
Msg 515, Level 16, State 2, Procedure
spInsertToDocumentFileCategoryRelation, Line 48
Cannot insert the value NULL into column 'DocumentId', table
'ffisherDB.arch.FileOfDocument'; column does not allow nulls. INSERT fails.
The statement has been terminated.
Msg 515, Level 16, State 2, Procedure
spInsertToDocumentFileCategoryRelation, Line 61
Cannot insert the value NULL into column 'DocumentId1', table
'ffisherDB.arch.DocumentRelation'; column does not allow nulls. INSERT
fails.
The statement has been terminated.
(1 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
I have four Key that set with SCOPE_IDENTITY(). the first one set exactly right but the others fails and above Errors report.
please help me.

Well, from error text it looks like your arch.Document table has non-nullable column DocumentTypeId.
And you're not filling that column here:
INSERT INTO [arch].[Document]
(
[DocumentNumber]
,[DocumentDate]
,[DateOfDocumentCreate]
,[IsDocumentDelete]
,[Address]
,[DocumentLevelTypeId]
)
So this column has its default value (I guess it is null), thus this insert fails, thus #DocumentId is null and remaining inserts fails too...

As per first error message DocumentTypeId field in Document table is not allowing null. You should insert a value into it in the insert query.
Change your insert to
INSERT INTO [arch].[Document]
(
[DocumentNumber]
,[DocumentDate]
,[DateOfDocumentCreate]
,[IsDocumentDelete]
,[Address]
,[DocumentLevelTypeId]
,[DocumentTypeId] --Add document type id here
)
VALUES
(
#DocumentNumber
,#DocumentDate
,'2015-5-12' --You better insert a DATE type or in ISO formatted 'yyyymmdd' string.
,#IsDocumentDelete
,#Address
,#DocumentLevelTypeId
,#DocumentTypeId --Insert a non - null value
)
Second & third error messages are due to first error.

Related

Get last identity of table and insert to new table

I'm trying to get the last identity from my table 'usergold' and insert it in a new table table with insert value. I used select "IDENT_CURRENT('UserGold') As userid", new value should be in userid.
But I'm getting an error when I put it in insert, I cannot create the trigger. Please check my code.
create trigger addrole
on UserGold
after Insert
as
Begin
select IDENT_CURRENT('UserGold') As userid
insert into AspNetUserRoles values(userid,'2c258e8d-c648-4b38-9b01-989d4dd525fe')
end
i tried
create trigger addrole
on UserGold
after Insert
as
Begin
declare
#userid nvarchar(50)
select #userid=userId from UserGold where userId=IDENT_CURRENT('UserGold')
insert into AspNetUserRoles(UserId,RoleId) values(#userid,'2c258e8d-c648-4b38-9b01-989d4dd525fe')
end
igot this error "Error converting data type nvarchar to numeric " from
select #userid=userId from UserGold where userId=IDENT_CURRENT('UserGold')
Your INSERT statement is not written correctly.
Try
INSERT INTO AspNetUserRoles ( [col_1_name], [col_2_name] )
VALUES (
( SELECT IDENT_CURRENT ( 'UserGold' ) ),
'2c258e8d-c648-4b38-9b01-989d4dd525fe'
);
Note: Replace the column holder names ( col_1_name, col_2_name ) with the actual column names being inserted to.

SQL Server trigger does not recognize inserted row

I have simple SQL Server trigger and for some reason it does not recognize INSERTED row.
Here is code:
-- code
DROP TABLE a;
GO
CREATE TABLE a
(
id INT IDENTITY(1,1) PRIMARY KEY,
v INT
)
GO
DROP TABLE a_audit;
CREATE TABLE a_audit
(
id INT,
v INT,
[updated_at] [DATETIME] NOT NULL DEFAULT GETDATE()
)
GO
CREATE TRIGGER [dbo].[trg_a]
ON [dbo].[a]
AFTER INSERT, UPDATE, DELETE
NOT FOR REPLICATION
AS
BEGIN
SET NOCOUNT ON;
PRINT 'start';
DECLARE #xmltmp xml = (SELECT * FROM inserted FOR XML AUTO);
PRINT CONVERT(NVARCHAR(MAX), #xmltmp);
-- INSERT INTO a_audit (id, v) VALUES (inserted.id, inserted.v);
END;
GO
INSERT INTO a (v)
VALUES (1);
WAITFOR DELAY '00:00:01.11';
INSERT INTO a (v)
VALUES (2);
GO
SELECT * FROM a;
PRINT 'done'
It produces this output
start
<inserted id="1" v="1"/>
(1 row affected)
start
<inserted id="2" v="2"/>
(1 row affected)
(2 rows affected)
done
So I see that INSERTED row does exist.
However, if I remove comment on insert statements the output is this:
Msg 4104, Level 16, State 1, Procedure trg_a, Line 14 [Batch Start Line 16]
The multi-part identifier "inserted.id" could not be bound.
Msg 4104, Level 16, State 1, Procedure trg_a, Line 14 [Batch Start Line 16]
The multi-part identifier "inserted.v" could not be bound.
What is wrong?
inserted is a table, not a function. To INSERT from another table you need to use a INSERT INTO... SELECT ... FROM statement:
INSERT INTO a_audit (id,v)
SELECT id,
v
FROM inserted;
You can't reference a table's columns unless you use a FROM. For example just running the below would give the error below:
SELECT a_audit.id, a.audit.v;
The multi-part identifier "a_audit.id" could not be bound.
You would have to a SELECT...FROM:
SELECT id, v
FROM a_audit;

SQL Server Insert Null error in spite of providing not null values

I am trying to do an insert but it is giving an error stating that credits cannot be null but I am not providing null. Attached Screenshot
Code: Insert into [dbo].[Course] values (12,'Java',1,1,1);
Error: Msg 515, Level 16, State 2, Procedure trgAfterInsert, Line 31
Cannot insert the value NULL into column 'Credits', table 'DemoCollege.dbo.Course'; column does not allow nulls. INSERT fails.
The statement has been terminated.
Trigger:
Create trigger trgAfterInsert2 ON [dbo].[Course]
After Insert
AS
Declare #cid int;
Declare #cname nvarchar(50);
Select #cid = i.CourseID from inserted i;
Select #cname = i.Title from inserted i;
Insert into dbo.CourseTemp values (#cid, #cname);
Print 'After insert trigger fired';
GO
There's an insert trigger on the table & that's where the error is being generated from.
There must be some logic in that is converting the provided credit value to a null value somehow.
Just provide the columns where you want to insert the values.
Insert into [dbo].[Course](ColName1, ColName2, ColName3, ColName4, etc..) values (12,'Java',1,1,1);
Most probably you're missing a col in the middle

Create a table and default column value to a received variable parameter

I'm working on a MSSQL stored procedure.
I receive a table valued parameter (#accountPropsTVP) and a single variable (#accountID) from the C# server.
#accountPropsTVP has 2 columns:
valueTypeID int
value varchar(max)
Note: I'm never sure how many rows will be in this table.
#accountID is an int.
I need to merge everything received into one table, so that it ends up looking like so:
#temporaryTable:
#accountID (always the same for all rows)
valueTypeID
value
Below is what I have tried, but I get an error:
Msg 112, Level 15, State 4, Procedure insertAccountProps, Line 20
Variables are not allowed in the CREATE TABLE statement.
CREATE PROCEDURE insertAccountProps
-- Received parameters
#accountID int,
#accountPropsTVP accountPropsTVP READONLY
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
-- declare new table
DECLARE #accountPropsTemp TABLE
(
accountID int not null DEFAULT (#accountID),
valueTypeID int not null,
value varchar(max) not null
)
-- insert received TVP into new temp table, so that we can manipulate it (tvp's are read only :( )
INSERT INTO #accountPropsTemp
SELECT *
FROM #accountPropsTVP
-- select all from TVP and add it into temp table created above
INSERT INTO dbo.accountsProps
SELECT *
FROM #accountPropsTemp
END
GO
Maybe there's a simpler way of doing this?
Your issue is here:
DECLARE #accountPropsTemp TABLE
(
accountID int not null DEFAULT (#accountID),
valueTypeID int not null,
value varchar(max) not null
)
You're assigning a variable as a default value which as the error message clearly states is not allowed.
The best option for this is to change your syntax to:
DECLARE #accountPropsTemp TABLE
(
accountID int not null,
valueTypeID int not null,
value varchar(max) not null
)
INSERT INTO
#accountPropsTemp
SELECT
#AccountID
,ValueTypeID
,Value
FROM
#accountPropsTVP

SQL Server check constraint failing on correct input

I'm using a check constraint on a table to restrict what values are inserted in the table..
Here's an explanation of what I'm trying to do
If any Product(sedan) is associated to a specific ObjLevel (Toyota) then the same Product cannot be associated to another specific ObjLevel (Lexus)
After I apply the check constraint on the table, any insert containing ObjLevel "toyota" or "lexus" fails..
create table ObjLevel(
OLID int identity,
Name varchar(50) not null
)
insert into ObjLevel values('Ford')
insert into ObjLevel values('Toyota')
insert into ObjLevel values('Lexus')
insert into ObjLevel values('GM')
insert into ObjLevel values('Infiniti')
create table ObjInstance(
OLIID int identity (20,1),
OLID int
)
insert into ObjInstance values(1)
insert into ObjInstance values(2)
insert into ObjInstance values(3)
insert into ObjInstance values(4)
insert into ObjInstance values(5)
create table Product(
PID int identity(50,1),
Name varchar(20)
)
insert into Product values ('sedan')
insert into Product values ('coupe')
insert into Product values ('hatchback')
create table ObjInstanceProd(
OLIID int,
PID int
)
create FUNCTION [dbo].[fnObjProd] (#Pid int) RETURNS bit WITH EXECUTE AS CALLER AS
BEGIN
DECLARE #rv bit
DECLARE #cnt int
SET #cnt = 0
SET #rv = 0
SET #cnt=
(Select Count(*) from ObjInstanceProd olip
join ObjInstance oli
on olip.OLIID = oli.OLIID
join ObjLevel ol
on ol.OLID = oli.OLID
where ol.Name in ('Toyota','Lexus')
and PID = #Pid)
if(#cnt>0)
SET #rv = 1
RETURN #rv
END
ALTER TABLE [dbo].[ObjInstanceProd] WITH CHECK ADD CONSTRAINT [CK_OLIP] CHECK ([dbo].[fnObjProd]([PID])=0)
--Insert Statement
insert into ObjInstanceProd(OLIID,PID) values (22,51)
Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "CK_OLIP". The conflict occurred in database "tmp", table "dbo.ObjInstanceProd", column 'PID'.
The statement has been terminated.
--Execute Function
select [dbo].[fnObjProd] (51)
0
Initially the Table ObjInstanceProd is empty.. So, no matter what value I put in the table, as long as the function in the constraint returns a 0, it should accept it.. But it does not..
The function is correctly returning a 0 (when executed independently), but for some reason, the check constraint returns a 1
When the CHECK constraint fires, the row is already in the table. Therefore, the function is called, and since there is a row returned by the query, the function returns 1, not 0. Try this. Drop the constraint, insert your row successfully, and then run this query:
SELECT OLIID, PID, dbo.fnObjProd([PID]) FROM dbo.ObjInstanceProd;
It should return 1 for every value of PID. Try to add the constraint now. It will fail for the same reason.
Have you considered using a trigger for this? If you use a check constraint, this will turn any multi-row insert or update into a cursor behind the scenes. This can absolutely kill performance and concurrency depending on how you touch your tables. Here is a simple INSTEAD OF INSERT trigger to prevent bad values going in with a single operation, even for a multi-row insert:
CREATE TRIGGER dbo.trObjProd
ON dbo.ObjInstanceProd
INSTEAD OF INSERT AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS
(
SELECT 1 FROM inserted
WHERE EXISTS
(
SELECT 1
FROM dbo.ObjInstanceProd AS olip
INNER JOIN dbo.ObjInstance AS oli
ON olip.OLIID = oli.OLIID
INNER JOIN dbo.ObjLevel AS ol
ON ol.OLID = oli.OLID
WHERE
ol.Name in ('Toyota','Lexus')
AND olip.PID = inserted.PID
)
)
BEGIN
INSERT ObjInstanceProd(OLIID, PID)
SELECT OLIID, PID FROM inserted;
END
ELSE
BEGIN
RAISERROR('At least one value was not good.', 11, 1);
SELECT OLIID, PID FROM inserted;
END
END
GO
If you're going to stick with a function, this is a much more efficient approach, however you need to define a way to determine that the current row being inserted is excluded from the check - I couldn't determine how to do that because there are no constraints on dbo.ObjInstanceProd. Is OLIID, PID unique?
ALTER FUNCTION [dbo].[fnObjProd]
(
#Pid INT
)
RETURNS BIT
WITH EXECUTE AS CALLER
AS
BEGIN
RETURN
(
SELECT CASE WHEN EXISTS
(
SELECT 1
FROM dbo.ObjInstanceProd AS olip
INNER JOIN dbo.ObjInstance AS oli
ON olip.OLIID = oli.OLIID
INNER JOIN dbo.ObjLevel AS ol
ON ol.OLID = oli.OLID
WHERE
ol.Name in ('Toyota','Lexus')
AND olip.PID = #Pid
) THEN 1 ELSE 0 END
);
END
GO

Resources