sql query iterating through query - sql

I wrote a stored procedure which returns contract status for anauthor. If author doesn't exist i'll return -900. So, this is what i did
CREATE PROCEDURE AUthorContract
#user varchar(10)
AS
IF(#user NOT IN(select Au_id from Authors))
BEGIn
RETURN -900
END
ELSE
BEGIN
select contract from from Authors where Au_id = #user
END
GO
However, when I give a valid author id as input, it returns -900 and if i give some id it goes into else and just returns 0 . So, I reversed them and entered correct id, but it still just returns 0 and not the contract value.
Can u please help me out the mistake i have been doing. The DB is pubs.

stored procedure can "return" three types of things:
int return value, via RETURN command
output parameter value, via parameter list: #YourPartameter anydatatype OUTPUT
result set: SELECT * FROM YourTable
your procedure does not have a RETURN command for normal exit, so it defaults to a value of zero. You need to check the result set in your application if the return value is zero.
try this to RETURN the contact value:
CREATE PROCEDURE AUthorContract
#user varchar(10)
AS
DECLARE #contract int
IF(#user NOT IN(select Au_id from Authors))
BEGIn
RETURN -900
END
ELSE
BEGIN
select #contract=contract from from Authors where Au_id = #user
END
RETURN #contract
GO
try this to use an OUTPUT parameter:
CREATE PROCEDURE AUthorContract
#user varchar(10), #contract varchar(30) OUTPUT
AS
IF(#user NOT IN(select Au_id from Authors))
BEGIn
RETURN -900
END
ELSE
BEGIN
select #contract=contract from from Authors where Au_id = #user
END
RETURN 0
GO
Here is the result set, with an explicit return:
CREATE PROCEDURE AUthorContract
#user varchar(10)
AS
IF(#user NOT IN(select Au_id from Authors))
BEGIn
RETURN -900
END
ELSE
BEGIN
select contract from from Authors where Au_id = #user
END
RETURN 0
GO

one way
CREATE PROCEDURE AUthorContract
#user varchar(10)
AS
IF NOT EXISTS(select 1 from Authors WHERE Au_id = #user )
BEGIN
SELECT -900 as contract -- this will return a result set
END
ELSE
BEGIN
select contract from Authors where Au_id = #user
END
GO
but a return status is not the same as a result set
if the proc is successful you will get 0, with return you can only use integers, use an output parameter if you need to return varchar

You're not returning the contract value. You are just selecting a scalar value to be outputed. The stored proc is returning 0 because it completed execution without a return value of something other than that.
Also, not sure if it is a typo, but you have an extra from in your select clause.

try:
IF(#user NOT IN(select Au_id from Authors))
BEGIn
declare #a int
set #a= -900
return #a
--print #a
END

Related

Return user information after validate user in stored procedure?

I have a stored procedure to validate a user. After validate right now I am returning true if user is validated but how can I return all the details of that user instead of true?
IF (#Flag='Authenticate')
BEGIN
IF EXISTS(SELECT UserID FROM UserInformation WITH(NOLOCK)WHERE UserName=#UserName and Password=#UserPassword )
BEGIN
INSERT INTO UserLoginHistory(UserId,LastLoggedIn)
SELECT #Userid,GETDATE()
select 'true' as [Output]
END
END
Try something like below query - You can declare more variables as needed, and store all those information in variables which you want to return.
IF (#Flag='Authenticate')
BEGIN
Declare #UserID varchar(50) = null
SELECT #UserID = UserID FROM UserInformation WITH(NOLOCK) WHERE UserName=#UserName and Password=#UserPassword )
IF (#UserID is not NULL)
BEGIN
INSERT INTO UserLoginHistory(UserId,LastLoggedIn)
SELECT #Userid,GETDATE()
SELECT #Userid
END
END
You don't need a separate "if" to check if the user already exists. You can put that all into a single query:
IF (#Flag = 'Authenticate')
BEGIN
INSERT INTO UserLoginHistory(UserId, LastLoggedIn)
SELECT v.Userid, GETDATE()
FROM (VALUES (#UserId)) v(UserId)
WHERE EXISTS (SELECT 1
FROM UserInformation ui
WHERE ui.UserName = #UserName AND ui.Password = #UserPassword
);
SELECT ui.*
FROM UserInformation ui
WHERE ui.UserName = #UserName AND ui.Password = #UserPassword;
END;
Also, I am concerned about #UserPassword. Hopefully that value is encrypted! You should not have clear-text passwords anywhere in an application that has a user other than you -- even for a demo or course.

SQL query to retrieve data based on either emailid or userid

I have to write a query for a login page where the user can enter either emailid(varchar datatype) or userid(int datatype). How do I write a query for this without knowing the datatype of the input?
CREATE PROCEDURE my_stored_procedure
#emailId nvarchar(50) = NULL,
#userId int = NULL
AS
SET NOCOUNT ON;
IF (#emailId IS NOT NULL) AND (LEN(#emailId) > 0)
SELECT * FROM MYTABLE WHERE EmailId = #emailId
ELSE
SELECT * FROM MYTABLE WHERE UserId = #UserId
GO
Your input parameter should be of varchar type.
Then in your procedure use ISNUMERIC function to check for number. Have two queries based on that with IF statement in case if it is int or varchar.
DECLARE #userInput VARCHAR(50)
IF ISNUMERIC(#userInput) = 1
BEGIN
-- Your query with userid
END
ELSE
BEGIN
-- Your query with emailid
END
Try this query it may help you.
DECLARE #emailid varchar(250),#userid bigint
set #emailid='A'
SET #userid=3
select * from yourtable
where case when #emailid='A' THEN 'A' ELSE emailid END=#emailid
AND case when #userid=0 THEN 0 ELSE userid END=#userid
Note: You should pass 'A' as default value for email_id and 0 for userid or else you can pass your required input

SQL Filter condition with value or Null

In the below procedure i may pass #Type value only sometimes otherwise it will be NULL.
How can i handle querying all data when NULL is passed and specific records when i pass a type. I don't want to build dynamic query for this simple handling.
CREATE PROCEDURE [dbo].[GetPatientImages]
(
#TenantId BIGINT,
#PatientId BIGINT,
#Type NVARCHAR(100)
)
AS
BEGIN
SET NOCOUNT ON
IF #TenantId IS NULL
RAISERROR('The value for #TenantID should not be null', 15, 1) -- with log
ELSE
BEGIN
SELECT
P.[DisplayFileName],
P.[StoredFileName],
P.[Location],
P.[Type],
P.[Description]
FROM
PatientImage P
WHERE P.PatientId=#PatientId AND P.TenantId=#TenantId AND P.[Type]=#Type
ORDER BY P.[Type] DESC
END
END
Try this:
WHERE P.PatientId=#PatientId AND P.TenantId=#TenantId AND
(#Type is null or P.[Type]=#Type)

How Can i Create procedure to forbid duplicated email?

I Have registration Form (asp.net) that include for text box . one of them is email text box . and iam using Linq To SQL .
i have been write procedure to forbid duplication
CREATE PROCEDURE CheckEmail ( #email NVARCHAR(50) )
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS ( SELECT C.Email
FROM Customer C
WHERE Email = #email )
BEGIN
INSERT INTO Customer
( Email )
VALUES ( #email )
END
ELSE
BEGIN
ROLLBACK TRANSACTION
END
END
is this a good way? How can I return error?
You can use RAISEERROR() function to return error. Also because you never tried to insert a duplicate email you do not need to ROLLBACK
CREATE PROCEDURE CheckEmail ( #email NVARCHAR(50) )
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS ( SELECT C.Email
FROM Customer C
WHERE Email = #email )
BEGIN
INSERT INTO Customer
( Email )
VALUES ( #email )
END
ELSE
BEGIN
DECLARE #ErrorMessage VARCHAR(100) = 'ERROR: Attempt to insert duplicate email address'
RAISERROR (#ErrorMessage,11,1)
RETURN
END
END
this is assuming you using sql-server if you are using a different DBMS just look up raise error function for your system.
Note: When you return SQL Error you need to make sure that application code knows how to handle it instead of just crashing.

SQL Procedure not working according to sequence

I wanted to write stored procedure for login table.
This procedure involves, checking if LogInID already exists, and if it exists then dont allow to insert record with same LogInID.
I procedure is as follows:
ALTER PROCEDURE logTRAN
#id varchar(25),
#pass varchar(25)
AS
BEGIN TRANSACTION
insert into login values(#id,#pass)
IF EXISTS (select count(*) from login where LogInID=#id)
BEGIN
PRINT 'USER ALREADY EXISTS'
ROLLBACK
END
ELSE
BEGIN
COMMIT TRANSACTION
END
I execute it as follows:
exec logTRAN '0L036','aaa' //this is repeated record with LogInID '0L036'
But Record gets inserted with following result:
(1 row(s) affected)
USER ALREADY EXISTS
Msg 266, Level 16, State 2, Procedure logTRAN, Line 0
Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 2, current count = 0.
What can be the mistake in my stored procedure?
Please guid me.
Change your SP to
CREATE PROCEDURE logTRAN
#id varchar(25),
#pass varchar(25)
AS
IF EXISTS (SELECT 1 FROM login WHERE LogInID = #id)
PRINT 'USER ALREADY EXISTS'
ELSE
INSERT INTO login VALUES(#id, #pass)
Here is SQLFiddle demo
On a side note: IMHO you don't need an SP for this at all. That what a UNIQUE constraint is for.
Change your query like below:
ALTER PROCEDURE logTRAN
(
#id varchar(25),
#pass varchar(25)
)
AS
BEGIN
IF EXISTS (SELECT LogInID from login where LogInID=#id)
BEGIN
PRINT 'User Already Exists'
END
ELSE
BEGIN
INSERT INTO login Values(#id,#pass)
END
END
RETURN
Or if you don't want to print just use:
ALTER PROCEDURE logTRAN
(
#id varchar(25),
#pass varchar(25)
)
AS
BEGIN
IF NOT EXISTS (SELECT LogInID from login where LogInID=#id)
BEGIN
INSERT INTO login Values(#id,#pass)
END
END
RETURN
I would recommend to use peterm's Answer. You should use SELECT 1 inplace of SELECT LogInID.