SQL Server syntax error Msg:156, Level:15, State:1 - sql-server

I'm trying to alter the following stored procedure, but I am getting a syntax error when I try to alter the procedure.
Msg 156, Level 15, State 1
Incorrect syntax near the keyword 'ELSE'. (Line 24)
Initially, I was executing the InsLoginAttempts incorrectly, but I corrected that.
Microsoft language reference doesn't seem to be any help https://msdn.microsoft.com/en-us/library/ms182717.aspx
SET ANSI_NULLS ON
GO
SET ANSI_NULLS ON
GO
ALTER PROCEDURE dbo.LogInUser
(#UserID varchar(50),
#Password varchar(15)
)
AS
BEGIN
SET NOCOUNT ON
DECLARE #UserExists varchar(50)
SET #UserExists = (SELECT UserID FROM Users WHERE UserID = #UserID)
DECLARE #CheckPassword varchar(15)
SET #CheckPassword = (SELECT Password FROM Users WHERE UserID = #UserID)
BEGIN
IF #UserExists IS NOT NULL
BEGIN
IF #Password = #CheckPassword
SELECT 'True' AS LoggedIn;
EXEC InsLoginAttempts #SPUserID = #UserID, #SPPassword = #Password, #Comment = 'Success';
ELSE
SELECT 'False' AS LoggedIn;
EXEC InsLoginAttempts #SPUserID = #UserID, #SPPassword = #Password, #Comment = 'Failed password attempt';
END
ELSE
SELECT 'False' AS LoggedIn;
EXEC InsLoginAttempts #SPUserID = #UserID, #SPPassword = #Password, #Comment = 'Failed username and password attempt';
END
END
GO
It's obviously a syntax error, but where is it?
EDIT: Also, I don't know if it's worth noting or not, but I'm also using a client called SQLPro for SQL Server.

Your script are missing a BEGIN and END
SET ANSI_NULLS ON
GO
SET ANSI_NULLS ON
GO
ALTER PROCEDURE dbo.LogInUser(
#UserID varchar(50),
#Password varchar(15)
)
AS
BEGIN
SET NOCOUNT ON
DECLARE #UserExists varchar(50)
SET #UserExists = (SELECT UserID FROM Users WHERE UserID = #UserID)
DECLARE #CheckPassword varchar(15)
SET #CheckPassword = (SELECT Password FROM Users WHERE UserID = #UserID)
BEGIN
IF #UserExists IS NOT NULL
BEGIN
IF #Password = #CheckPassword
BEGIN
SELECT 'True' AS LoggedIn;
EXEC InsLoginAttempts #SPUserID = #UserID, #SPPassword = #Password, #Comment = 'Success';
END
ELSE
BEGIN
SELECT 'False' AS LoggedIn;
EXEC InsLoginAttempts #SPUserID = #UserID, #SPPassword = #Password, #Comment = 'Failed password attempt';
END
END
ELSE
BEGIN
SELECT 'False' AS LoggedIn;
EXEC InsLoginAttempts #SPUserID = #UserID, #SPPassword = #Password, #Comment = 'Failed username and password attempt';
END
GO

Related

Incorrect syntax near GOTO label in SQL Server stored procedure

I am using a GOTO statement inside a try block and also in catch block in a stored procedure.When it comes to the definition of GOTO label after END catch, it shows incorrect syntax error. below is the procedure. Error comes at 'AuditLog :' in the procedure. please help me with this.
ALTER PROCEDURE [dbo].[Proc_PIP_Employee]
#Flag int = 1,
#Empid int = 0,
#Name nvarchar(500) = '',
#Designation nvarchar(200) = '',
#Department nvarchar(200) = '',
#DateofJoin datetime = '' ,
#Phone nvarchar(3000) = '',
#Isactive int = 1,
#LoginUser nvarchar(500) = ''
AS
BEGIN
SET NOCOUNT ON ;
DECLARE #r int;
BEGIN TRY
BEGIN TRANSACTION
DECLARE #errorMessage VarChar(8000),
#errorSeverity Int,
#errorState Int,
#ReturnId Int,
#AlCode varchar(50),
#AlDesc varchar(1000),
#AlOp varchar(50),
#AlStatus varchar(50)
IF (#Flag = 1)
BEGIN
IF EXISTS (SELECT 1 FROM dbo.PIP_Employee
GROUP BY Name, Phone
HAVING COUNT(ID) > 0
AND Name = #Name AND Phone = #Phone)
BEGIN
SET #ReturnId = 0
SET #AlCode = 'ERROR_1001'
SET #AlDesc = CONCAT('Add Record of ',#Name,' failed due to duplicate entry')
SET #AlOp = 'ADD'
SET #AlStatus = 'ERROR'
GOTO AuditLog
END
ELSE
BEGIN
INSERT INTO dbo.PIP_Employee (Name, Designation, Department, DateofJoin, Phone, IsPresent)
VALUES (#Name, #Designation, #Department, #DateofJoin, #Phone, #Isactive)
SET #ReturnId = 1
END
END
COMMIT TRANSACTION
END TRY
BEGIN CATCH
SET #AlCode = ERROR_SEVERITY()
SET #AlDesc = ERROR_MESSAGE()
SET #AlOp = 'SQL TRANSACTION FAILURE'
SET #AlStatus = ERROR_STATE();
GOTO AuditLog
IF (##trancount > 0)
ROLLBACK TRANSACTION
END CATCH
AuditLog :
INSERT INTO dbo.PIP_AuditLog (Aud_Code, Aud_Desc, Aud_Operation, Aud_Status, Aud_Createddate, Aud_ActionBy)
VALUES (#AlCode, #AlDesc, #AlOp, #AlStatus, GETDATE(), #LoginUser)
SET NOCOUNT OFF
END
AuditLog : seems to be an incorrect syntax.
If you are not using an IDE with syntax checking like SQL Server Management Studio, you might want to check out some free tools like https://ubitsoft.com/t-sql-beautilyzer/.
This indicates that line 68 is bad. Namely that labels should NOT have a space between the label and the ':'

Check transaction committed and if so return a value

I want to insert a new user (Email address) into a table of users. If successful (no duplicate), insert basic configurations for new user to other tables, and return some data to client. If not successful, receive relevant notification in dataset in C# project.
Here is sample code so you can easily comment on it
ALTER PROCEDURE [dbo].[CreateUser]
#Email nvarchar(256),
#Password nvarchar(256)
AS
BEGIN
declare #UserID uniqueidentifier;
declare #ConfigID uniqueidentifier;
declare #TopMostNode uniqueidentifier;
BEGIN TRANSACTION;
select #UserID = NEWID();
select #ConfigID = newid();
insert into Users (UserID,Email,Password,CurrentConfig)
values(#UserID, #Email, #Password, #ConfigID);
INSERT INTO Configs (ConfigID, OwnerID, DisplayName, LastPrintID)
VALUES (#ConfigID,#UserID, 'Default Config', 1);
COMMIT TRANSACTION
END
That code is almost complete. Just need to add a SELECT to return the new keys. In case of an error, you will get an exception. EG:
ALTER PROCEDURE [dbo].[CreateUser]
#Email nvarchar(256),
#Password nvarchar(256)
AS
BEGIN
declare #UserID uniqueidentifier;
declare #ConfigID uniqueidentifier;
declare #TopMostNode uniqueidentifier;
BEGIN TRANSACTION;
select #UserID = NEWID();
select #ConfigID = newid();
insert into Users (UserID,Email,Password,CurrentConfig)
values(#UserID, #Email, #Password, #ConfigID);
INSERT INTO Configs (ConfigID, OwnerID, DisplayName, LastPrintID)
VALUES (#ConfigID,#UserID, 'Default Config', 1);
COMMIT TRANSACTION
select #UserID UserID, #ConfigID ConfigID;
END
Here is one possibility where you return a recordset with the data you require and a flag to indicate whether the user already existed or not.
alter procedure [dbo].[CreateUser]
(
#Email nvarchar(256)
, #Password nvarchar(256)
)
as
begin
declare #UserID uniqueidentifier, #ConfigID uniqueidentifier, #TopMostNode uniqueidentifier, #UserExists bit = 0;
select #UserID = UserID, #UserExists = 1 from Users where Email = #Email;
if #UserExists = 0 begin
begin transaction;
set #UserID = newid();
set #ConfigID = newid();
insert into Users (UserID, Email, [Password], CurrentConfig)
values (#UserID, #Email, #Password, #ConfigID);
insert into Configs (ConfigID, OwnerID, DisplayName, LastPrintID)
values (#ConfigID, #UserID, 'Default Config', 1);
commit transaction
end
-- Return whether the user already exists or not and the user id
select #UserExists, #UserId
return 0;
end
Another way to return data to the app is using output parameters e.g.
alter procedure [dbo].[CreateUser]
(
#Email nvarchar(256)
, #Password nvarchar(256)
, #UserId uniqueidentifier out
, #UserExists bit out
)
as
begin
declare #ConfigID uniqueidentifier, #TopMostNode uniqueidentifier;
set #UserExists = 0;
select #UserID = UserID, #UserExists = 1 from Users where Email = #Email;
if #UserExists = 0 begin
begin transaction;
set #UserID = newid();
set #ConfigID = newid();
insert into Users (UserID, Email, [Password], CurrentConfig)
values (#UserID, #Email, #Password, #ConfigID);
insert into Configs (ConfigID, OwnerID, DisplayName, LastPrintID)
values (#ConfigID, #UserID, 'Default Config', 1);
commit transaction
end
return 0;
end

my stored procedured worlking properly in local mssql but but not in godaddy mylittleadmin

this is my sql code for login when execte it in my local mssql server
working properly but when i exected in godaddy's mylittleadmin is not
alter proc [dbo].[Loginuser]
#Username nvarchar(100),
#Password nvarchar(100)
as
begin
Declare #Retrycount int
Declare #count int
Declare #Accountlocked bit
Declare #Rolename nvarchar(20)
select #Accountlocked = Islocked
from tbl_Userinfo where Email = #Username
if(#Accountlocked = 1)
begin
select 1 as Accountlocked ,0 as authenticated,0 as Retryattempts
end
else
begin
select #count = count(Email) from tbl_Userinfo where Email=#Username and [Password]=#Password
if(#count=1)
begin
update tbl_Userinfo set Retryattempts = 0
where Email = #Username
select 0 as Accountlocked,1 as authenticated,0 as Rertyattempts
UPDATE tbl_Userinfo
SET LastLogin = GETDATE()
WHERE Email = #Username
SELECT #Rolename = RoleName FROM tbl_Roles WHERE RoleId = (select RoleId from tbl_Userinfo where Email=#Username and [Password]=#Password)
SELECT 1 as [ReturnCode], #Username as [Uname], #Rolename as [Roles]
end
else
begin
select #Retrycount = IsNull(Retryattempts,0)
from tbl_Userinfo where Email = #Username
set #Retrycount=#Retrycount+1
if(#Retrycount <= 3)
begin
update tbl_Userinfo set Retryattempts = #Retrycount
where Email = #Username
select 0 as Accountlocked,0 as authenticated,#Retrycount as Retryattempts
end
else
begin
update tbl_Userinfo set Retryattempts = #Retrycount,
Islocked = 1,Lockeddatetime = GETDATE()
where Email = #Username
select 0 as Accountlocked,0 as authenticated,0 as Retryattempts
end
end
end
end
this is output i want
I want output like in given image but it is working correct in local mssql server when i execute it in godaddy's mylitleadmin it is returning null in Roles columns
This is role table
Can any help me with solution please.

Authenticate user in stored procedure

I am new to sql and I am not sure what's wrong with my stored procedure.
User inputs user name & password which are my input parameters and if it is correct then return 'Login Success', if UN is incorrect than return 'Incorrect UN' or if PW is incorrect than return 'Incorrect PW'. In the stored procedure I have an IF Else statement and it is only hitting the first IF statement not other.
Please have a look my stored procedure:
CREATE PROCEDURE [dbo].[AuthenticateUser]
#UserName varchar(15),
#Password varchar(15),
#Role varchar(25) OUTPUT
AS
SET NOCOUNT ON
BEGIN
DECLARE #UN VARCHAR(25)
DECLARE #PW VARCHAR(25)
SELECT #UN = UserName, #PW = Password FROM LogIn
IF (#UN != #UserName COLLATE SQL_Latin1_General_CP1_CS_AS)
BEGIN
SET #Role = 'Incorrect User Name'
END
ELSE
BEGIN
IF (#PW != #Password COLLATE SQL_Latin1_General_CP1_CS_AS)
BEGIN
SET #Role = 'Incorrect Password'
END
ELSE
BEGIN
SET #Role = 'Logged in Successfully'
END
END
SELECT #Role
END
Thank you for your help
You are doing this:
SELECT #UN = UserName, #PW = Password FROM LogIn
IF (#UN != #UserName COLLATE SQL_Latin1_General_CP1_CS_AS)
These comparisions #UN = UserName and #PW = Password should be made in the WHERE clause to help in proper filtering of rows.
Here is the code rewritten (you can change to using your own table name)
Drop Table TestLogin
GO
Create Table TestLogin
(
UserName VarChar (20),
Password VarChar(20)
)
Insert TestLogin Values ('One', 'Two')
GO
Drop PROCEDURE AuthenticateUser
GO
CREATE PROCEDURE AuthenticateUser
#UserName varchar(15),
#Password varchar(15),
#Role varchar(25) OUTPUT
AS
If ((SELECT Count (*) From TestLogin Where UserName COLLATE SQL_Latin1_General_CP1_CS_AS = #Username And Password COLLATE SQL_Latin1_General_CP1_CS_AS = #Password) = 0)
Begin
If ((SELECT Count (*) From TestLogin Where UserName COLLATE SQL_Latin1_General_CP1_CS_AS = #Username) = 0)
Begin
Select #Role = 'Incorrect User Name'
End
Else
Begin
Select #Role = 'Incorrect Password'
End
End
Else
Begin
Select #Role = 'Logged in Successfully'
End
GO
Declare #Role VarChar (100)
Exec AuthenticateUser 'One', 'Two', #Role Output
Print #Role
Exec AuthenticateUser 'One', 'TwoX', #Role Output
Print #Role
Exec AuthenticateUser 'OneX', 'Two', #Role Output
Print #Role
The three examples provided at the end show you how the procedure behaves when you give it a good login, or either parameter is incorrect.
Change it to a SELECT COUNT(1) FROM userLogin.... and then use ExecuteScalar() on the SqlDataReader object.
As a side note, it's not a good idea to store your passwords in the DB in plain text, but hash them instead, preferably with a salt value.
Try this instead:
Create PROCEDURE [dbo].[AuthenticateUser]
#UserName varchar(15),
#Password varchar(15),
#Role varchar(25) OUTPUT
AS
SET NOCOUNT ON
BEGIN
If Not Exists (Select 1 From LogIn Where UserName = #UserName) Set #Role = 'Incorrect UserName'
Else If Not Exists (Select 1 From LogIn Where Password = #Password) Set #Role = 'Incorrect Password'
Else Set #Role = 'Logged in Successfully'
Select #Role
END
Generally it is not good idea to give an attacker a cue "name is OK, now guess PWD". Plus, password should be at least case sensitive. For this purpose:
select #un=username from LogIn
where username=#username
and cast(password as varbinary(max)) = cast(#password as varbinary(max))
if #un is null
set #role = 'UN or PWD is incorrect'
else
set #role = 'Success'
If you want to give hints:
select #un=username from LogIn
where username=#username
if #un is null
set #role = 'UN not found'
else
begin
select #un=username from LogIn
where username=#username
and cast(password as varbinary(max)) = cast(#password as varbinary(max))
if #un is null
set #role = 'password incorrect'
else
set #role = 'Success'
end
P.S.: I hope username is unique in your table.

SQL Insert multiple records to Triggered table

On SQL Agent job I'm downloading data from main table (X). If the status equal 'WW' or 'WXY' I just want to all records insert into another table (Y) where I have created a trigger. Could you give me advise what should I change in my trigger definition? I receive error message when I try insert multiple records to DB2.Y table (agent job failed)
First code (downloading new data)
DECLARE #STARTTIME datetime
DECLARE #TIME datetime
DECLARE #ENDTIME datetime
SET #TIME=(SELECT MAX(Time) FROM DB2.Y)
SET #STARTTIME=(select dateadd(hour,1,getdate()))
SET #ENDTIME=(SELECT MAX(TIME) FROM DB1.X where TIME is not null)
IF #TIME = #ENDTIME
BEGIN
TRUNCATE TABLE DB2.Y;
INSERT INTO DB2.Y (Time) Values (#TIME)
END
ELSE
BEGIN
TRUNCATE TABLE DB2.Y
INSERT INTO DB2.Y ([Serv],[Status])
SELECT [SERV],[STATUS] FROM DB1.X WHERE TIME > #TIME and [SERV]='Description' and ([STATUS]='WW' or [STATUS]='WXY') ;
UPDATE DB2.Y
SET [Time]= #ENDTIME
END
The trigger code:
USE DB2
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[TriggerName] ON Y
AFTER INSERT AS
DECLARE #SERV varchar(40)
DECLARE #STATUS varchar(3)
SET #SERV=(SELECT [SERV] FROM inserted)
SET #STATUS=(SELECT [STATUS] FROM inserted)
IF #STATUS in ('WW', 'WXY')
BEGIN
DECLARE #MSG varchar(500)
SET #MSG = 'Job "' + #SERV + '" failed!!!'
EXEC msdb.dbo.sp_send_dbmail #recipients=N'myemail#domain.com', #body= #MSG, #subject = #MSG, #profile_name = 'profilename'
END
INSERTED can contain multiple rows for multi-row INSERTs - it runs once per operation, not once per row.
Try a trigger like this instead:
USE DB2
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[TriggerName] ON Y
AFTER INSERT AS
DECLARE #SERV varchar(40)
DECLARE #STATUS varchar(3)
IF EXISTS(SELECT [Status] FROM Inserted WHERE [STATUS] in ('WW', 'WXY'))
BEGIN
DECLARE #MSG varchar(8000)
INSERT INTO JobLog(Serv, Status)
SELECT Serv, Status FROM Inserted WHERE [STATUS] in ('WW', 'WXY')
SET #MSG = CAST(##ROWCOUNT as nvarchar) + 'Job(s) failed - see log for details'
EXEC msdb.dbo.sp_send_dbmail #recipients=N'myemail#domain.com', #body= #MSG, #subject = #MSG, #profile_name = 'profilename'
END
SELECT
Try something like this...
CREATE TRIGGER [dbo].[TriggerName] ON Y
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SERV varchar(40),#STATUS varchar(3), #MSG varchar(500)
Select [SERV], [STATUS] INTO #Temp
FROM inserted
Where [STATUS] IN ('WW', 'WXY')
Declare Cur CURSOR FOR
SELECT [SERV], [STATUS] FROM #Temp
OPEN Cur
FETCH NEXT FROM Cur INTO #SERV, #STATUS
WHILE ##FETCH_STATUS = 0
BEGIN
SET #MSG = 'Job "' + #SERV + '" failed!!!'
EXEC msdb.dbo.sp_send_dbmail #recipients=N'myemail#domain.com'
, #body= #MSG
, #subject = #MSG
, #profile_name = 'profilename'
FETCH NEXT FROM Cur INTO #SERV, #STATUS
END
CLOSE Cur
DEALLOCATE Cur
END
You could use a cursor to resolve your error. The cursor below iterates over all inserted records with a STATUS of either WW or WXY and sends out an email for each of them.
DECLARE error_cursor CURSOR FOR
SELECT [SERV],[STATUS] FROM inserted
WHERE [STATUS] in ('WW', 'WXY')
OPEN error_cursor
FETCH NEXT FROM error_cursor
INTO #SERV, #STATUS
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE MSG varchar(500)
SET #MSG = 'Job "' + #SERV + '" failed!!!'
EXEC msdb.dbo.sp_send_dbmail #recipients=N'myemail#domain.com', #body= #MSG, #subject = #MSG, #profile_name = 'profilename'
FETCH NEXT FROM vendor_cursor
INTO #SERV, #STATUS
END
CLOSE error_cursor;
DEALLOCATE error_cursor;

Resources