Verification of adding an identical record in SQL - sql-server

I need support, I have a procedure and I need it to return an error when I try to add the same name in the ProductName column:
USE [Northwind]
GO
/****** Object: StoredProcedure [dbo].[AddNewProduct] Script Date: 14.09.2021 18:15:53 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[AddNewProduct]
#ProductName nvarchar(40), #SupplierID int, #CategoryID int, #QuantityPerUnit nvarchar(20), #UnitPrice money, #UnitsInStock smallint, #UnitsOnOrder smallint, #ReorderLevel smallint, #Discontinued bit
as
If #ProductName = #ProductName
Begin
Declare #count int, #ProductID int
Insert into Products
(
ProductName ,
SupplierID ,
CategoryID ,
QuantityPerUnit,
UnitPrice,
UnitsInStock,
UnitsOnOrder,
ReorderLevel,
Discontinued)
values
(#ProductName,
#SupplierID ,
#CategoryID ,
#QuantityPerUnit,
#UnitPrice,
#UnitsInStock,
#UnitsOnOrder,
#ReorderLevel,
#Discontinued )
End
else
Begin
DECLARE #ErrorMessage NVARCHAR(4000);
SET #ErrorMessage = 'DDDD';
RAISERROR (#ErrorMessage, 16, 1);
end
I want a message to appear when I try to add the same record
Can you tell me what I am doing wrong or what needs to be added / changed?

As has been mentioned in the comments, this logic has no right being in the procedure, it should be part of the table's definition, as a UNIQUE CONSTRAINT or UNIQUE INDEX. I'm going to use a UNIQUE CONSTRAINT here, which would mean the DDL for the CONSTRAINT would look like this:
ALTER TABLE dbo.Products ADD CONSTRAINT UQ_ProductName UNIQUE (ProductName);
Then, you just need your procedure to look like this:
ALTER PROCEDURE [dbo].[AddNewProduct] #ProductName nvarchar(40),
#SupplierID int,
#CategoryID int,
#QuantityPerUnit nvarchar(20), --Why is this an nvarchar if it's a quantity?
#UnitPrice money,
#UnitsInStock smallint,
#UnitsOnOrder smallint,
#ReorderLevel smallint,
#Discontinued bit AS
BEGIN
INSERT INTO dbo.Products(ProductName,
SupplierID,
CategoryID,
QuantityPerUnit,
UnitPrice,
UnitsInStock,
UnitsOnOrder,
ReorderLevel,
Discontinued)
VALUES (#ProductName, #SupplierID, #CategoryID, #QuantityPerUnit, #UnitPrice, #UnitsInStock, #UnitsOnOrder, #ReorderLevel, #Discontinued);
END;
GO
If you then attempt to insert a duplicate value you'll get the following error:
Violation of UNIQUE KEY constraint 'UQ_ProductName'. Cannot insert duplicate key in object 'dbo.Products'. The duplicate key value is ({Duplicate Product Name}).

Related

Simple insert stored procedure not working

I am trying to make a simple stored procedure but it's not working. When I execute the procedure with my parameters in it, below is the following:
ALTER proc [dbo].[sp_NewProduct]
#ProductName nvarchar(50),
#ProductNumber nvarchar(25),
#MakeFlag bit,
#FinishedGoodsFlag bit,
#Color nvarchar(15),
#SafetyStockLevel smallint,
#ReorderPoint smallint,
#StandardCost money,
#ListPrice money,
#DaysToManufacture int,
#SellStartDate date,
#rowguid uniqueidentifier,
#ModifiedDate datetime
as
insert dbo.product
(Name,
ProductNumber,
MakeFlag,
FinishedGoodsFlag,
Color,
SafetyStockLevel,
ReorderPoint,
StandardCost,
ListPrice,
DaysToManufacture,
SellStartDate,
rowguid,
ModifiedDate)
values
(#ProductName,
#ProductNumber,
#MakeFlag,
#FinishedGoodsFlag,
#Color, #SafetyStockLevel,
#ReorderPoint,
#StandardCost,
#ListPrice,
#DaysToManufacture,
#SellStartDate,
#rowguid,
#ModifiedDate)
Here's the execute query with values of each column:
exec sp_NewProduct 'AR-5516','105',0,1,'Red',5,5,0.00,0.00,5,'2018-05-01',newid(),getdate()
Seems you are dealing with wrong procedure syntax! use following snippets:
Create or Alter proc [dbo].[sp_NewProduct] (#ProductName nvarchar(50), #ProductNumber nvarchar(25), #MakeFlag bit, #FinishedGoodsFlag bit, #Color nvarchar(15), #SafetyStockLevel smallint, #ReorderPoint smallint, #StandardCost money, #ListPrice money, #DaysToManufacture int, #SellStartDate date, #rowguid uniqueidentifier, #ModifiedDate datetime)
As
Begin
Insert dbo.product (Name,ProductNumber,MakeFlag,FinishedGoodsFlag,Color,SafetyStockLevel,ReorderPoint,StandardCost,ListPrice, DaysToManufacture,SellStartDate,rowguid,ModifiedDate) values (#ProductName,#ProductNumber,#MakeFlag,#FinishedGoodsFlag,#Color, #SafetyStockLevel,#ReorderPoint,#StandardCost,#ListPrice,#DaysToManufacture,#SellStartDate,#rowguid,#ModifiedDate)
End
Go
Exec sp_NewProduct 'AR-5516','105',0,1,'Red',5,5,0.00,0.00,5,'2018-05-01',#Id,#DateTime;
If you still getting error, store newid()'s value and GetDate()'s value in temporary variable, and call through this variable!
Declare #Id AS UniqueIdentifier = NewId()
Declare #DateTime as DateTime = GetDate()
Exec sp_NewProduct 'AR-5516','105',0,1,'Red',5,5,0.00,0.00,5,'2018-05-01',#Id,#DateTime;

How to display the result of stored procedure in the temporary table?

I want to display the result of a stored procedure in a temporary table.
I have the following code:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[insertpropertylisting]
#propertyname VARCHAR(150),
#propertyaddress VARCHAR(250),
#propertyprice MONEY,
#availableunits VARCHAR(100),
#propertyid INT OUTPUT
AS
BEGIN
INSERT INTO propertylisting (propertyname, propertyaddress, propertyprice, availableunits)
VALUES (#propertyname, #propertyaddress, #propertyprice, #availableunits)
PRINT #propertyname
SELECT #propertyaddress AS 'address'
SET #propertyid = SCOPE_IDENTITY()
SELECT
#propertyname = propertyname,
#propertyaddress = propertyaddress,
#propertyprice = propertyprice,
#availableunits = availableunits
FROM
propertylisting
WHERE
property_id = #propertyid
RETURN #propertyid
END
CREATE TABLE #propertylisting
(
propertyname VARCHAR(150),
propertyaddress VARCHAR(250),
propertyprice MONEY,
availableunits VARCHAR(100),
propertyid INT
)
INSERT INTO #propertylisting
EXEC [dbo].[insertpropertylisting]
SELECT
propertyname, propertyaddress, propertyprice, availableunits
FROM
#propertylisting
DROP TABLE #propertylisting
I am not getting the output as table.
A few problems that I can see:
Not supplying parameters to the SP.
Stand-alone SELECT in the middle of SP that you don't want (also a PRINT).
The lack of a batch separator when issuing the ALTER PROCEDURE command.
You are assigning the values of the inserted row back to the variables and not actually selecting them back to the caller.
It's recommended to always include the column list on INSERT statements, and specially when doing INSERT INTO EXEC.
First make some changes to the SP; remove unused statements and parameters (including the OUT property of the parameter since it seems you aren't using it). You can return inserted values with the OUTPUT clause of the INSERT statement, including computed and IDENTITY columns.
ALTER procedure [dbo].[insertpropertylisting]
#propertyname varchar(150),
#propertyaddress varchar(250),
#propertyprice money,
#availableunits varchar(100)
as
BEGIN
insert into propertylisting (
propertyname,
propertyaddress,
propertyprice,
availableunits)
OUTPUT
inserted.propertyname,
inserted.propertyaddress,
inserted.propertyprice,
inserted.availableunits,
inserted.property_id -- Can return IDENTITY and computed columns
values(
#propertyname,
#propertyaddress,
#propertyprice,
#availableunits)
END
After you run this ALTER, you can bring inserted records with a INSERT INTO EXEC. Make sure to pass proper values to the SP.
Create table #propertylisting
(
propertyname varchar(150),
propertyaddress varchar(250),
propertyprice money,
availableunits varchar(100),
propertyid int
)
Insert into #propertylisting (
propertyname,
propertyaddress,
propertyprice,
availableunits,
propertyid)
Exec [dbo].[insertpropertylisting]
#propertyname = 'Value',
#propertyaddress = 'Value',
#propertyprice = 999,
#availableunits = 'Value'
select
propertyname,
propertyaddress,
propertyprice,
availableunits,
propertyid
from
#propertylisting
Drop table #propertylisting
Try to use like this first create temp table and then execute the sql procedure
USE [Joins]
GO
/****** Object: StoredProcedure [dbo].[insertpropertylisting] Script Date: 1/29/2019 3:55:43 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[insertpropertylisting]
#propertyname varchar(150),
#propertyaddress varchar(250),
#propertyprice money,
#availableunits varchar(100),
#propertyid int OUTPUT
as
BEGIN
insert into propertylisting(propertyname,propertyaddress,propertyprice,availableunits)
values(#propertyname,#propertyaddress,#propertyprice,#availableunits)
print #propertyname
select #propertyaddress as 'address'
SET #propertyid=SCOPE_IDENTITY()
SELECT #propertyname=propertyname,#propertyaddress=propertyaddress,#propertyprice=propertyprice,
#availableunits=availableunits ,#propertyid FROM propertylisting WHERE property_id=#propertyid
-- Return #propertyid u can write in selecting it self
END
Create table #propertylisting
(
propertyname varchar(150),
propertyaddress varchar(250),
propertyprice money,
availableunits varchar(100),
propertyid int
)
Insert into #propertylisting
Exec [dbo].[insertpropertylisting]

Error Msg 213: Column name or number of supplied values does not match table definition

I created a table with a stored procedure and I'm trying to insert data into it, but I'm getting this error
Msg 137, Level 15, State 2, Line 49
Must declare the scalar variable "#EmployeeID")
Please help!
Create Table Humanresource.Employee
(
EmployeeID char(3) constraint pkemployeeid primary key,
FirstName varchar(20) not null,
LastName varchar(20) not null,
Emp_Address varchar(30) not null,
Title char(30) constraint ckTitle check(Title in ('Executive','Senior Executive','Management Trainee','Event Manager','Senior Event Manager')),
Phone varchar(20) check(Phone like '[0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9]')
)
Stored procedure:
create procedure Auto_EmpID
#FirstName varchar(20),
#LastName varchar(20),
#Address varchar(30),
#Title varchar(30),
#Phone varchar(20)
AS
Declare #EmployeeID char(3)
if exists (select EmployeeID From HumanResource.Employee Where EmployeeID = 'E101')
BEGIN
Select
#EmployeeID = Max(right(EmployeeID, 2))
from HumanResource.Employee
Select
#EmployeeID = CASE
When #EmployeeID >= 0 AND #Employeeid < 9
Then 'E0' + convert(char(3), #EmployeeID + 1)
When #EmployeeID >= 9 AND #EmployeeID < 99
Then 'E' + convert(char(3), #EmployeeID + 1)
END
END
Else
set #Employeeid = 'E101'
insert into HumanResource.Employee
Values(#EmployeeID, #FirstName, #LastName, #Address, #Title, #Phone)
Return
Exec Auto_EmpID 'Bamidele','Ajose','Lagos','11-1111-111-111'
exec Auto_Empid 'Kunle','Awele','Ikeja','22-3332-655-897'
exec auto_empid 'John','George','Benin','33-5555-7654-443'
select * from humanresource.employee
insert into humanresource.employee(#EmployeeID, #FirstName, #LastName, #Address, #Title, #Phone)
values(#EmployeeID = 'e101', 'Baley', 'Carles', 'Los Angeles', '23-3445-434-344')
These 2 lines have a lot of problems:
insert into humanresource.employee(#EmployeeID,#FirstName,#LastName,#Address,#Title,#Phone)
values(#EmployeeID='e101','Baley','Carles','Los Angeles','23-3445-434-344')
You don't need to prefix the # symbol to column names. That should only be used with variables.
The column list contains 6 columns, but you are only supplying 5 values in the values clause. Please add the 6th value or remove the column where you don't want to insert.
If you want to use the value 'e101', you can directly insert that. If you want to use the variable #employeeID, just pass that. The assignment #employeeID = 'e101' is wrong inside the values clause. You could just do set #employeeID = 'e101 to assign the value before the insert statement.
#employeeID is declared as char(3), so even if you wanted to assign the value 'e101' to it before the insert statement, the value would get truncated to 'e10'. So, you must declare it as char(4) at least.
Another thing is that your stored procedure takes 5 input parameters, but you pass only 4 when calling it. If you want to pass only some parameters instead of all, you need to specify default values for each parameter while creating the procedure, something like this:
create procedure Auto_EmpID
#FirstName varchar(20) = 'somefirstname',
#LastName varchar(20) = 'somelastname',
#Address varchar(30) = 'somecity',
#Title varchar(30) = 'sometitle',
#Phone varchar(20) = '111-111-111'

Cannot insert the value NULL into column '', table column does not allow nulls. INSERT fails

Code:
ALTER PROCEDURE [dbo].[SP_LMS_dealerorusercreation_IUDS]
#dealrid bigint,
#rid bigint,
#stateid bigint,
#regonid bigint,
#Locid bigint,
#pid varchar(MAX),
#address varchar(max),
#dealrname varchar(25),
#landno bigint,
#mobno bigint,
#altcontno bigint,
#email varchar(35),
#desig varchar(25),
#reporting varchar(30),
#status int,
#action varchar(10),
#CompanyId Uniqueidentifier
AS
DECLARE #TranStatus VARCHAR(5)
BEGIN TRY
BEGIN TRANSACTION
IF(#action='Insert')
BEGIN
INSERT INTO LMS_dealerorusercreation(
rid,
stateid,
regonid,
Locid,
addres,
dealrname,
landno,
mobno,
altcontno,
email,
desig,
reporting,
status,
CompanyId
)
VALUES(
#rid,
#stateid,
#regonid,
#Locid,
#address,
#dealrname,
#landno,
#mobno,
#altcontno,
#email,
#desig,
#reporting,
#status,
#CompanyId
)
SELECT #dealrid = dealrid FROM LMS_dealerorusercreation WHERE mobno = #mobno AND email = #email
EXEC [dbo].[SP_LMS_SetDealerProductMapping]
#dealerId = #dealrid,
#prodid = #pid
SET #TranStatus='TRUE';
END
IF(#action='Update')
BEGIN
UPDATE LMS_dealerorusercreation set rid= #rid,
stateid=#stateid,
regonid=#regonid,
Locid=#Locid,
addres=#address,
dealrname=#dealrname,
landno=#landno,
mobno=#mobno,
altcontno=#altcontno,
email=#email,
desig=#desig,
reporting=#reporting,
status=#status
WHERE dealrid=#dealrid
SET #TranStatus='TRUE';
END
IF(#action='Delete')
BEGIN
DELETE FROM LMS_dealerorusercreation WHERE dealrid=#dealrid
SET #TranStatus='TRUE';
END
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
DECLARE #AI VARCHAR(MAX)
DECLARE #EM VARCHAR(MAX);
SET #AI = 'Not Provided'
SET #EM = ERROR_MESSAGE();
EXEC USP_SetException
#ExceptionDetail = #EM,
#AdditionalInfo = #AI
SET #TranStatus='FALSE';
END CATCH
SELECT #TranStatus;
The error am getting is
Cannot insert the value NULL into column 'dealrid', table 'DB_LMS.dbo.LMS_dealerorusercreation'; column does not allow nulls. INSERT fails.
You need to do one of two things, either...
ensure that you pass in a non-null value for the column, or;
ensure that your column accepts a null value if that is a desired property of the field.
Errors I see in the code.
While inserting into the table LMS_dealerorusercreation, you never selected dealrid column. Please select the same.
INSERT INTO LMS_dealerorusercreation(
rid,
stateid,
regonid,
Locid,
addres,
dealrname,
landno,
mobno,
altcontno,
email,
desig,
reporting,
status,
CompanyId,
dealrid
)
VALUES(
#rid,
#stateid,
#regonid,
#Locid,
#address,
#dealrname,
#landno,
#mobno,
#altcontno,
#email,
#desig,
#reporting,
#status,
#CompanyId,
#dealrid
)
it is juat as the error message states.
you are trying to do an insert to a table where dealrid has been created with not null. if you look at your insert statement, you are not selecting and passing a value to it.

In stored procedure if null value found it should skip that insert query

I have 2 tables one is
peson contains(personid Identity, firstname,Lastname,PlaceOfBirth,Gender)
and another
Education contains (Eduid identity, egreename,boardUniver,yearOfPassing,obtainedMarks, personid)
now my problem is that each person have more than 1 degree, but some have 1 or 2 degree, so how can i skip the insert queries?
First Table
Create table person(personid int Identity(1,1) primary key, firstname nvarchar(40), Lastname nvarchar(40), PlaceOfBirth nvarchar(40), Gender nvarchar(10))
Second Table
create table Education(Eduid int identity(1,1) primary key, Degreename nvarchar(40), boardUniver nvarchar(40), yearOfPassing nvarchar(40), obtainedMarks numeric(10,2), personid int,
constraint fk_eduPerson foreign key (personid) references person(personid))
Procedure to store information
Create procedure EmpDetails
(
#Firstname nvarchar(40), #Lastname nvarchar(40), #PlaceOfBirth nvarchar(40), #Gender nvarchar(8),
#Degreename0 int, #boardUniver0 nvarchar(40), #yearOfPassing0 nvarchar(20), #obtainedMarks0 int,
#Degreename1 int, #boardUniver1 nvarchar(40), #yearOfPassing1 nvarchar(20), #obtainedMarks1 int,
#Degreename2 int, #boardUniver2 nvarchar(40), #yearOfPassing2 nvarchar(20), #obtainedMarks2 int,
)
AS BEGIN
declare #personid int
INSERT INTO person(firstname,Lastname,PlaceOfBirth,Gender) values(#firstname,#Lastname,#PlaceOfBirth,#Gender)
SELECT #personid=##IDENTITY
if(#Degreename0 !=NULL)
BEGIN
INSERT INTO Education(Degreename,boardUniver,yearOfPassing,obtainedMarks, personid) values (#Degreename0,#boardUniver0,#yearOfPassing0,#obtainedMarks0, #personid)
END
IF(#Degreename1 !=null)
BEGIN
INSERT INTO Education(Degreename,boardUniver,yearOfPassing,obtainedMarks, personid) values (#Degreename1,#boardUniver1,#yearOfPassing1,#obtainedMarks1, #personid)
END
IF(#Degreename2!=null)
BEGIN
INSERT INTO Education(Degreename,boardUniver,yearOfPassing,obtainedMarks, personid) values (#Degreename2,#boardUniver2,#yearOfPassing2,#obtainedMarks2,#personid)
END
END
This is not working.. this inserts all rows empty.. is there any other solution to do this?
Please give suggestion if any other.. Thanks
Try IS NOT NULL instead of != NULL. In most relational databases, the comparison operators return false if either input is NULL, even if they both are. Here is a SQL Fiddle demonstrating the behavior.
(Sorry. That SQL Fiddle really works.)
Admittedly, this is confusing, as that fact should mean all your INSERTs are skipped. I don't see anything here that would insert empty rows.
Try this one -
Create procedure EmpDetails
(
...
)
AS BEGIN
DECLARE #personid INT
INSERT INTO Person (firstname, Lastname, PlaceOfBirth, Gender)
SELECT #firstname, #Lastname, #PlaceOfBirth, #Gender
SELECT #personid = SCOPE_IDENTITY()
INSERT INTO Education (Degreename, boardUniver, yearOfPassing, obtainedMarks, PersonID)
SELECT a = #Degreename0, b = #boardUniver0, c = #yearOfPassing0, d = #obtainedMarks0, e = #personid
WHERE #Degreename0 IS NOT NULL
UNION ALL
SELECT #Degreename1, #boardUniver1, #yearOfPassing1, #obtainedMarks1, #personid
WHERE #Degreename1 IS NOT NULL
UNION ALL
SELECT #Degreename2, #boardUniver2, #yearOfPassing2, #obtainedMarks2, #personid
WHERE #Degreename2 IS NOT NULL
END

Resources