SQL Server Stored Procedure Error on Insert using TRY CATCH - sql

I wrote a stored procedure which uses encryption algorithm to insert a row into a table. The procedure is executing successfully, but no row is added.
My code:
CREATE TABLE dbo.[User]
(
UserID INT IDENTITY(1,1) NOT NULL,
Email NVARCHAR(64) NOT NULL,
PasswordHash BINARY(64) NOT NULL,
FirstName NVARCHAR(40) NULL,
LastName NVARCHAR(40) NULL,
CONSTRAINT [PK_User_UserID] PRIMARY KEY CLUSTERED (UserID ASC)
)
CREATE PROCEDURE dbo.addUser
#pEmail NVARCHAR(64),
#pPassword NVARCHAR(64),
#pFirstName NVARCHAR(40) = NULL,
#pLastName NVARCHAR(40) = NULL,
#responseMessage NVARCHAR(250) OUTPUT
AS
BEGIN
BEGIN TRY
INSERT INTO dbo.[User] (Email, PasswordHash, FirstName, LastName)
VALUES(#pEmail, HASHBYTES('SHA2_512', #pPassword), #pFirstName, #pLastName)
SET #responseMessage = 'Success'
END TRY
BEGIN CATCH
SET #responseMessage = ERROR_MESSAGE()
END CATCH
END
DECLARE #responseMessage NVARCHAR(250)
EXEC dbo.addUser
#pEmail = 'Admin',
#pPassword = '123',
#pFirstName = 'Admin',
#pLastName = 'Administrator',
#responseMessage=#responseMessage OUTPUT
After executing the procedure, no rows have been added to the table.

Related

SQL Server Trigger After Insert is Repeating old valus

Can someone please explain why this trigger would start failing and insert the same record repeatedly? It seems as though there is something wrong with the variables. The purpose of the trigger is to copy the inserted record from the Employee table to the EmployeeHistory table. I set the trigger and it runs fine. But then when my coworker runs some insert scripts, it starts repeating the same old value from my last execution of an insert, instead of the new values that they are trying to insert.
I have already recoded this to not use variables, but I would still like to know why this doesn't work as expected.
CREATE TRIGGER [dbo].[triggerEmployee_AfterInsert]
ON [dbo].[Employee]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #EmployeeID varchar(25)
DECLARE #FirstName varchar(25)
DECLARE #LastName varchar(50)
DECLARE #FullName varchar(75)
DECLARE #EmailAddress varchar(50)
DECLARE #ManagerID varchar(15)
DECLARE #JobTitle varchar(50)
DECLARE #EmployeeStatus varchar(10)
DECLARE #Office varchar(25)
SELECT #EmployeeID = [dbo].[Employee].[EmployeeID]
,#FirstName = [dbo].[Employee].[FirstName]
,#LastName = [dbo].[Employee].[LastName]
,#FullName = [dbo].[Employee].[FullName]
,#EmailAddress = [dbo].[Employee].[EmailAddress]
,#ManagerID = [dbo].[Employee].[ManagerID]
,#JobTitle = [dbo].[Employee].[JobTitle]
,#EmployeeStatus = [dbo].[Employee].[EmployeeStatus]
,#Office = [dbo].[Employee].[Office]
FROM [dbo].[Employee]
INSERT INTO [dbo].[EmployeeHistory] (
EmployeeID
,FirstName
,LastName
,FullName
,EmailAddress
,ManagerID
,JobTitle
,EmployeeStatus
,Office
)
VALUES (
#EmployeeID
,#FirstName
,#LastName
,#FullName
,#EmailAddress
,#ManagerID
,#JobTitle
,#EmployeeStatus
,#Office
)
END
GO
ALTER TABLE [dbo].[Employee] ENABLE TRIGGER [triggerEmployee_AfterInsert]
GO
Rewriting the SELECT statement to use the INSERTED table fixed the issue.
SELECT #EmployeeID = [EmployeeID]
,#FirstName = [FirstName]
,#LastName = [LastName]
,#FullName = [FullName]
,#EmailAddress = [EmailAddress]
,#ManagerID = [ManagerID]
,#JobTitle = [JobTitle]
,#EmployeeStatus = [EmployeeStatus]
,#Office = [Office]
FROM INSERTED

Why is this Salt CAST as NVARCHAR(32) in SQL Server?

I learned about storing password in SQL server database with HASHING and Salt. This code was online and had no really useful comment section for it so I want to ask here.
Why is #salt cast as NVARCHAR(36) here?
I tried different lengths like NVARCHAR(50) and in the database, Salt is still saved as a string of length 36.
For example:
B25243D7-A126-48A8-90F2-5898572F54D2
E29E1CEF-DBE1-4373-9510-A911BA0C8672
CREATE TABLE dbo.[User1]
(
UserID INT IDENTITY(1,1) NOT NULL,
LoginName NVARCHAR(40) NOT NULL,
PasswordHash BINARY(64) NOT NULL,
Salt UNIQUEIDENTIFIER,
FirstName NVARCHAR(40) NULL,
LastName NVARCHAR(40) NULL,
CONSTRAINT [PK1_User_UserID] PRIMARY KEY CLUSTERED (UserID ASC)
)
CREATE PROCEDURE dbo.uspAddUser1
#pLogin NVARCHAR(50),
#pPassword NVARCHAR(50),
#pFirstName NVARCHAR(40) = NULL,
#pLastName NVARCHAR(40) = NULL,
#responseMessage NVARCHAR(250) OUTPUT
AS
BEGIN
SET NOCOUNT ON
DECLARE #salt UNIQUEIDENTIFIER=NEWID()
BEGIN TRY
INSERT INTO dbo.[User1] (LoginName, PasswordHash, Salt, FirstName, LastName)
VALUES(#pLogin, HASHBYTES('SHA2_512', #pPassword+CAST(#salt AS NVARCHAR(36))), #salt, #pFirstName, #pLastName)
SET #responseMessage = 'Success'
END TRY
BEGIN CATCH
SET #responseMessage = ERROR_MESSAGE()
END CATCH
END
DECLARE #responseMessage NVARCHAR(250)
EXEC [dbo].[uspAddUser1]
#pLogin = 'admin2',
#pPassword = '123456',
#pFirstName = 'John',
#pLastName = 'Smith',
#responseMessage = #responseMessage OUTPUT
SELECT * FROM [dbo].[User1]
It is because of DECLARE #salt UNIQUEIDENTIFIER=NEWID(). in sql server NEWID() function returns a UNIQUEIDENTIFIER of character length 36

Stored Procedure With Input Output Scope Identity

I have two tables namely User and UserRole, where I want to pass the values via stored procedures with below tables. I need help how I can create a procedure which inserts into both the tables assuming a user has only one role i.e either User or Admin.
The Id parameter inserted into second table must be the Id of User Table.
Please suggest me.
CREATE TABLE [dbo].[User](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL,
[Username] [nvarchar](50) NULL,
[Password] [nvarchar](50) NULL,
)
CREATE TABLE [dbo].[UserRole](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] Foreign Key References User(ID)NOT NULL,
[Role] [nvarchar](50) NULL
)
CREATE PROCEDURE [dbo].[AddUserRole]
#Name VARCHAR(50),
#Username DATETIME,
#Password INT,
#Role NVARCHAR(50),
#Id INT OUT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [WH].[dbo].[User]
(
Name,
Username,
Password
)
VALUES
(
# Name,
#Username,
#Password
);
SET # Id = SCOPE_IDENTITY();
INSERT INTO [WH].[dbo].[UserRole]
(
UserId,
Role
)
VALUES
(
#Id,
# Role
);
END;
Use output method, detail here
try Something like this
DECLARE #MyTableVar table( Id int);
INSERT INTO [WH].[dbo].[User] (Name, Username, Password)
OUTPUT INSERTED.Id INTO #MyTableVar
VALUES (#Name, #Username, #Password);
INSERT INTO [WH].[dbo].[UserRole] (UserId, Role )
SELECT Id, #Role FROM #MyTableVar;
Now this working fine !
CREATE TABLE [dbo].[TempUser](
[Id] [int] IDENTITY(1,1) NOT NULL Primary key,
[Name] [nvarchar](50) NULL,
[Username] [nvarchar](50) NULL,
[Password] [nvarchar](50) NULL,
)
CREATE TABLE [dbo].[TempUserRole](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] Foreign Key References TempUser(ID)NOT NULL,
[Role] [nvarchar](50) NULL
)
--ALTER TABLE TempAddUserRole DROP CONSTRAINT FK__TempUserR__UserI__503293D2;
EXEC TempAddUserRole 'Gulshan','12 sep 2018','1','Admin'
EXEC TempAddUserRole 'Gulshan','12 sep 2018','1','Admin',
ALTER PROCEDURE [dbo].[TempAddUserRole]
#Name VARCHAR(50),
#Username DATETIME,
#Password INT,
#Role NVARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
declare #Id INT
INSERT INTO [TempUser]
(
Name,
Username,
Password
)
VALUES
(
#Name,
#Username,
#Password
);
SET #Id = SCOPE_IDENTITY();
INSERT INTO [TempUserRole]
(
UserId,
Role
)
VALUES
(
#Id,
#Role
);
END;

Error converting data type varchar to int.?

My table is below
CREATE TABLE Customers
(
CustomerID int identity(1,1) not null primary key,
Name varchar(50) not null,
PhoneNumber varchar(20) not null
constraint chk_PhoneNumber check(PhoneNumber not like '%[^0-9]%'),
DoorNo varchar(50) not null,
StreetName varchar(50) not null,
City varchar(50) not null,
Statee varchar(50) not null,
Zipcode int not null
)
My stored procedure:
ALTER PROCEDURE stp_customers_insert
(#customerid int,
#name varchar(50),
#phone varchar(50),
#doorno varchar(50),
#streetname varchar(50),
#city varchar(50),
#state varchar(50),
#zip int)
AS
BEGIN
IF EXISTS (SELECT CustomerID FROM Customers WHERE CustomerID = #customerid)
BEGIN
RAISERROR ('employee id already exists', 1, 1)
END
ELSE
BEGIN
INSERT INTO Customers (Name, PhoneNumber, DoorNo, StreetName, City, Statee, Zipcode)
VALUES (#name, #phone, #doorno, #streetname, #city, #state, #zip)
END
END
Sample call:
exec stp_customers_insert 'ram', '674673932', '122', '5th cross', 'trichy', 'tamilnadu', 620001
I get this error:
Msg 8114, Level 16, State 5, Procedure stp_customers_insert, Line 23
Error converting data type varchar to int.
The problem appears to be that your stored procedure expects 8 parameters:
stp_customers_insert(#customerid int, #name varchar(50), #phone varchar(50),
#doorno varchar(50), #streetname varchar(50), #city varchar(50),
#state varchar(50), #zip int)
but you are only passing 7 parameters when you actually call the proc:
exec stp_customers_insert 'ram','674673932','122','5th cross','trichy','tamilnadu',620001
If you don't know or don't want to perform the duplicate check on the CustomerID, then you could slightly modify your call to just pass NULL:
exec stp_customers_insert NULL, 'ram','674673932','122','5th cross','trichy','tamilnadu',620001
As an aside, if the proc is not even inserting the CustomerID, and this field is auto increment, then I don't see the point of passing it. Instead, you might want to consider using a unique constraint to achieve the same.
exec stp_customers_insert 1,'ram','674673932','122','5thcross','trichy','tamilnadu',620001
You have to pass #customerid value in procedure parameters - then it will execute without error.
In your table structure CustomerID is defined as INT. But as your stored procedure is defined in this format:
stp_customers_insert(#customerid int,#name ....
You are sending ram as value for customerid in
exec stp_customers_insert 'ram','674673932'....
Correct this to:
exec stp_customers_insert '*enter the CustId value here*','ram','674673932'....
Replace *enter the CustId value here* with the CustomerID
Also change:
insert into Customers(Name,PhoneNumber,DoorNo,StreetName,City,Statee,Zipcode) values(#name,#phone,#doorno,#streetname,#city,#state,#zip)
To include CustomerID as:
insert into Customers(CustomerID,Name,PhoneNumber,DoorNo,StreetName,City,Statee,Zipcode) values(#customerid,#name,#phone,#doorno,#streetname,#city,#state,#zip)
I suggest remove #customerid from sp CustomerID is auto increment field so no need to pass any value for CustomerID. It should be like this:
alter procedure stp_customers_insert(#name varchar(50),#phone varchar(50),#doorno varchar(50),#streetname varchar(50),#city varchar(50),#state varchar(50),#zip int)
as
begin
if exists(select CustomerID from Customers where Name = #name ,phone = #phone ,doorno = #doorno ,streetname = #streetname ,city= #city,state= #state , zip = #zip )
begin
raiserror('employee id already exists',1,1)
end
else
begin
insert into Customers(Name,PhoneNumber,DoorNo,StreetName,City,Statee,Zipcode) values(#name,#phone,#doorno,#streetname,#city,#state,#zip)
end
end
exec stp_customers_insert 'ram','674673932','122','5th cross','trichy','tamilnadu',620001

Error converting data type varchar to int error in stored procedure

My stored procedure is
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Customer_Registrations]
#type varchar(50) = null,
#Customer_ID int = null,
#Customer_Name varchar(50) = null,
#Email varchar(50) = null,
#Password varchar(50) = null,
#Mobile varchar(50) = null
AS
BEGIN
SET NOCOUNT ON;
IF #type = 'select'
BEGIN
SELECT *
FROM ssshub..Customer_Master
END
IF #type = 'specific'
BEGIN
SELECT *
FROM ssshub..Customer_Master
WHERE Customer_ID = #Customer_ID
END
IF #type = 'insert'
BEGIN
INSERT INTO [dbo].[Customer_Master]([Customer_Name], [Email],[Password], [Mobile], [SDate])
VALUES ('#Customer_Name', '#Email', '#Password', '#Mobile', CURRENT_TIMESTAMP)
END
END
And my table
This is working fine
This query works fine but when I am trying to insert it using stored procedure it throws an error.
I have an identity specification for customer_id on so no need to insert it
INSERT INTO [dbo].[Customer_Master] ([Customer_Name], [Email], [Password], [Mobile], [SDate])
VALUES('ewcewc', 'dewdw#dwc.com', 'dewdwd', '9999999999', CURRENT_TIMESTAMP)
Now when I am trying to execute my stored procedure with the following statement
exec customer_registrations 'insert', 'dsad', 'test#test.com', 'pass', '9999900000'
I get:
Error converting data type varchar to int
Lining up your arguments with the parameters:
'insert' -> #type varchar(50)
'dsad' -> #Customer_ID int
'test#test.com' -> #Customer_Name varchar(50)
'pass' -> #Email varchar(50)
'9999900000' -> #Password varchar(50)
-> #Mobile varchar(50) = null
...you can see that 'dsad' has no way of being understood as an int. Maybe there's a problem elsewhere as well, but at the very least, the stored procedure is not being called correctly.
Update:
If your intent was to omit some arguments that aren't relevant in a certain case, you have to use named parameters; otherwise, arguments can only be applied in the same order the parameters appear:
exec customer_registrations
'insert',
#Customer_Name = 'dsad',
#Email = 'test#test.com',
#Password = 'pass',
#Mobile = '9999900000';
Please pass null value in procedure while you insert the data in table. Run the procedure below way while inserting data in table. you should me manage all the parameter of procedure. you are not passed value of Customer_ID, so that's way error occur.
EXEC [dbo].[Customer_Registrations] 'insert',null,'ewcewc', 'dewdw#dwc.com', 'dewdwd', '9999999999'
Create Database Test
Create Table Employee
(
EmpId int identity(1,1) not null primary Key,
EmpName varchar(50),
Address varchar(50),
MobileNo int
)
Select * From [dbo].[Employee]
Alter Table [dbo].[Employee] Alter Column MobileNo Bigint
Insert into [dbo].[Employee] values('Harsh Kumar','Banglore','9748342075')
Create Proc MyProc
As
Select * From [dbo].[Employee]
EXEC MyProc
Create Proc SP_GetEmp
#EmpId int,
#EmpName varchar(50),
#Address varchar(50),
#MobileNo int
As
Insert into [dbo].[Employee](EmpId, EmpName, Address, MobileNo) Values(#EmpId, #EmpName, #Address, #MobileNo)
EXEC SP_GetEmp 'Rahul Kr','Pune', 8250707544
EXEC MyProc
Error:- Error converting data type varchar to int.