T SQL Nested IF...ELSE in BEGIN...END - sql-server

I would like some guidance on why there are issues with this procedure. I seem to get an error that states "Incorrect syntax near the keyword 'END'."
I've added comments where I think the issues are. labeled (x) and (y) in the in-code-comments. I used DataGrip for syntax highlighting and that's how I know these pairings exist. But I still don't understand why.
I am aware that a CASE statement could solve this issue. But I would like to know why it is not working with IF...ELSE
CREATE PROCEDURE AuthenticateUser(
#UserName NVARCHAR(50),
#Password NVARCHAR(50),
#Result INT OUTPUT
) AS
BEGIN -- Cannot find a corresponding END
SET NOCOUNT ON
DECLARE #userID INT
IF exists(SELECT UserID FROM Users WHERE UserName = #UserName)
BEGIN -- paired with END (y)
SET #userID = (SELECT UserID FROM Users WHERE UserName = #UserName AND Password = dbo.EncryptPassword(#Password, Salt))
IF #userID IS NULL -- Paired with END (x)
SET #Result = 0
ELSE
SET #Result = 1
END -- paired with IF (x)
ELSE
SET #Result = 0
END -- paired with BEGIN (y)
GO

How about try adding a BEGIN and END label on each IF ELSE condition. Something like this.
CREATE PROCEDURE AuthenticateUser
(
#UserName NVARCHAR(50) ,
#Password NVARCHAR(50) ,
#Result INT OUTPUT
)
AS
BEGIN -- Cannot find a corresponding END
SET NOCOUNT ON
DECLARE #userID INT
IF EXISTS ( SELECT 1
FROM Users
WHERE UserName = #UserName )
BEGIN -- paired with END (y)
SET #userID = ( SELECT UserID
FROM Users
WHERE UserName = #UserName
AND Password = dbo.EncryptPassword(#Password,
Salt)
)
IF #userID IS NULL -- Paired with END (x)
BEGIN
SET #Result = 0
END
ELSE
BEGIN
SET #Result = 1
END
END -- paired with IF (x)
ELSE
BEGIN
SET #Result = 0
END
END -- paired with BEGIN (y)
GO

#Edwinj
Nothing wrong in If else block , there is issue in your code
Salt (Password = dbo.EncryptPassword(#Password, Salt)))
Salt is neither it Number not veritable or string so function EncryptPassword will fail with error.

Related

Get value from store or store and get if not exists

what I want to achieve is a way to get previously generated or generate, store and return data, in a way, which could be used as function - needed to join or APPLY in UPDATE scripts.
So, having data generate function:
ALTER FUNCTION generateData()
RETURNS NVARCHAR(20)
AS
BEGIN
RETURN 'asdyukyuk' --some rng related algorithm
END
And "get or generate, save and get" procedure:
ALTER PROCEDURE getOrGenerateAndGet (#orig NVARCHAR(20), #result NVARCHAR(20) OUTPUT)
AS
BEGIN
IF #orig IS NULL
BEGIN
SET #result = NULL
END
ELSE
BEGIN
DECLARE #hash VARBINARY(64) = dbo.getHash(#orig)
SELECT #result = GENERATED_DATA FROM STORED_DATA WHERE HASH = #hash
IF #result IS NULL
BEGIN
SET #result = dbo.generateData()
INSERT INTO STORED_DATA (HASH, GENERATED_DATA) VALUES (#hash, #result)
END
END
RETURN 1
END;
GO
And UPDATE script:
UPDATE FRAGILE_DATA SET FRAGILE_COLUMN = getOrGenerateAndGet(FRAGILE_COLUMN)
it's obviously not working, because getOrGenerateAndGet is not function.
However, with function way:
CREATE FUNCTION getOrGenerateAndGet (#orig NVARCHAR(20))
RETURNS NVARCHAR(20)
AS
BEGIN
DECLARE #result NVARCHAR(20)
IF #orig IS NULL
BEGIN
SET #result = NULL
END
ELSE
BEGIN
DECLARE #hash VARBINARY(64) = dbo.getHash(#orig)
SELECT #result = GENERATED_DATA FROM STORED_DATA WHERE HASH = #hash
IF #result IS NULL
BEGIN
SELECT #result = dbo.generateData()
EXEC sp_executesql N'INSERT INTO STORED_DATA (HASH, GENERATED_DATA) VALUES (#hash, #result)'
END
END
RETURN #result
END;
GO
it's still not working, because "Only functions and some extended stored procedures can be executed from within a function."
Is there any way to achieve this, without enabling sql command shell?

print error if there is a name already in the table

//My code should be something like this
CREATE PROCEDURE REGISTRATION
#USERNAME VARCHAR(20)
AS
BEGIN
BEGIN IF
SELECT USERNAME FROM USERS WHERE USERNAME = #USERNAME
PRINT 'USER ALREADY EXITS'
ELSE
IF #USERNAME = 'NULL'
PRINT 'Fill username'
end
end
Try This :
CREATE PROCEDURE REGISTRATION
#USERNAME VARCHAR(20)
AS
BEGIN
declare #count as int
select #count = COUNT(*) from USER where USERNAME =#USERNAME
if(#count > 0)
print 'USER ALREADY EXITS' -- Record Exists
else
print 'Fill username' -- NULL
end
use exists. Also, formatting gets overlooked and is important
CREATE PROCEDURE REGISTRATION
#USERNAME VARCHAR(20)=''
AS
BEGIN
IF exists(SELECT 1 FROM USERS WHERE USERNAME = #USERNAME)
begin
PRINT 'USER ALREADY EXITS'
end
ELSE
begin
PRINT 'Fill username'
end
end

Fail to assigned to the output parameter in stored procedure

ALTER PROCEDURE [dbo].[loginCheck]
#uid AS int ,
#pwd AS nchar(50) ,
#result AS INT OUTPUT
AS
BEGIN
IF EXISTS(SELECT * FROM seller WHERE S_id = #uid AND S_password = #pwd)
BEGIN
SET #result = 1
EXEC(#result)
END
ELSE
BEGIN
SET #result = 0
EXEC(#result)
END
END
This is the code of my stored procedure, I want to check out the id and password when login, so I check if there exists this data in my database.
declare #result int
exec loginCheck 1, '123456', #result output
select #result
I use these to test my stored procedure, but it informed there exist grammatical errors around "1", when i debug by each statement, I found #result has changed to 1, so why i got this error, and how to fix it? Thanks

How to know TSQL Stored Procedure Update Executed

How can I check if my TSQL stored procedure updated within the stored procedure in order to create a proper message?
Example:
ALTER PROCEDURE [dbo].[pUpdate]
#id uniqueidentifier,
#status int,
#message VARCHAR(100) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
UPDATE [database].[dbo].[user]
SET status = #status
WHERE Id = #id
END
IF (SUCCESSFUL)
BEGIN
#message = 'Success!'
END
What are some possible ways to check if successful without using the parameters again?
This is what I currently use:
SELECT COUNT(*)
WHERE status = #status AND id = #id
Are there any other ways? I want to know for my knowledge and reference. Thanks.
Have you checked out ##ROWCOUNT? Might be what you're looking for (see this for details: http://technet.microsoft.com/en-us/library/ms187316.aspx). Basically it returns the number of rows affected by the last statement. I'd imagine if it were not "successful", it would be zero rows.
ALTER PROCEDURE [dbo].[pUpdate]
#id uniqueidentifier,
#status int,
#message VARCHAR(100) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
UPDATE [database].[dbo].[user]
SET status = #status
WHERE Id = #id
END
IF (##ROWCOUNT > 0)
BEGIN
#message = 'Success!'
END
ELSE
BEGIN
#message = 'Not success!'
END
You can use a try catch block and log the success or failure to a table.
BEGIN TRY
BEGIN TRANSACTION
-- Add Your Code Here
-- Log Success to a log table
COMMIT
END TRY
BEGIN CATCH
-- Log failure to a log table
ROLLBACK
END CATCH
I would use ##ERROR system variable to check whether the last sentence was successfull (error # = 0) or not (error # > 0 ):
USE Database;
GO
BEGIN
UPDATE TableName
SET ColumnA = 4
WHERE ColumnB = 1;
END
IF (##ERROR = 0)
BEGIN
PRINT N'Successfull Update';
GO
END
You can go deeper into Microsoft MSDN here: http://technet.microsoft.com/es-es/library/ms188790.aspx
ALTER PROCEDURE [dbo].[pUpdate]
#id uniqueidentifier,
#status int,
#message VARCHAR(100) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
UPDATE [database].[dbo].[user]
SET status = #status
WHERE Id = #id
END
IF (##ROWCOUNT > 0)
BEGIN
SELECT #message = 'Success!'
END
ELSE
BEGIN
SELECT #message = 'Not success!'
END

Stored procedure is not working

I have created a stored procedure to retrieve some details based on the certain values passed to a parameter. THis requires switching between the SQLs to be executed by stored procedure. Following is the code:
USE [DFS]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[DAFS]
#EmailID Nvarchar(128),
#clientID int,
#userType Varchar(50),
#Success numeric output,
#msg varchar(100) output
AS
BEGIN
if #userType='Normal User'
IF EXISTS (SELECT 1 FROM dbo.Allcdn
WHERE EmailID = #EmailID AND ClientID = #clientID)
begin
set #Success=0
set #msg='Carry on ....'
end
else
begin
set #Success=6
set #msg='Not allowed ...'
END
end
else
Begin
IF EXISTS (SELECT 1 FROM dbo.Alcon
WHERE EmailID = #EmailID AND ClientID = #clientID)
BEGIN
set #Success=0
set #msg='Carry on...'
END
END
End
end
END
The entire processing is based on the variable #userType. Not sure why the stored procedure is not compiling.
Formatting is your friend, just with a quick glance, it appears you have too many ENDs -- See SQL Fiddle with working Demo:
CREATE PROCEDURE [dbo].[DAFS]
#EmailID Nvarchar(128),
#clientID int,
#userType Varchar(50),
#Success numeric output,
#msg varchar(100) output
AS
BEGIN
if #userType='Normal User'
IF EXISTS (SELECT 1 FROM dbo.Allcdn
WHERE EmailID = #EmailID AND ClientID = #clientID)
begin
set #Success=0
set #msg='Carry on ....'
end
else
begin
set #Success=6
set #msg='Not allowed ...'
END
else
Begin
IF EXISTS (SELECT 1 FROM dbo.Alcon
WHERE EmailID = #EmailID AND ClientID = #clientID)
BEGIN
set #Success=0
set #msg='Carry on...'
END
END
end

Resources