I have a stored proc (SS2008) that takes a couple int ids and needs to look up if they exist in a table before adding a record. I have an int output param I would like to return and set its value based on what occrured. I have this so far, but it always returns 1. Can someone point me in the right direction?
BEGIN TRY
IF EXISTS
(
SELECT * FROM tbMap WHERE (cId= #CId)
)
SET #result = -1; -- This C User is already mapped
ELSE IF EXISTS
(
SELECT * FROM tbMap WHERE (dId = #DId)
)
SET #result = -2; -- This D User is already mapped
ELSE
INSERT INTO tbMap (
Login
, Email
, UserName
, CId
, DId)
SELECT
#UserName
, usr.EmailAddress
, usr.UserName
, #CId
, #DId
FROM tbUser usr WHERE usr.iUserID = #DId
SET #result = 1;
RETURN
END TRY
What am I missing? Thanks for any tips.
Cheers,
~ck in San Diego
Put the multiple statements for the last ELSE in a BEGIN/END block otherwise the last SET is always executed.
ELSE
BEGIN
INSERT INTO tbMap (
Login
, Email
, UserName
, CId
, DId)
SELECT
#UserName
, usr.EmailAddress
, usr.UserName
, #CId
, #DId
FROM tbUser usr WHERE usr.iUserID = #DId
SET #result = 1;
RETURN
END
END TRY
Have you tried using SELECT #result instead of SET? Also, I'm assuming the calling code has the #result parameter marked as Output?
Related
At the very end of the Stored procedure a SELECT statement is made to display the contents of the Table including function that will simultaneously populate fields in the table.
Here is the Select Statement:
IF #type = 'SH'
SELECT DISTINCT *
FROM #History
ORDER BY 1, 2, 3, 4, 5
ELSE
SELECT DISTINCT AmhazName
,Activity
,ServiceName
,Sarid
,PerformedDate
,UserRole
,Details
,dbo.ufn_SarHistoryActionText(sarid, status, performeddate) AS [ActionText]
,FullName
,CategoryDescription
,StatusDescription
,ActionPerformed
,Case
when Details like '%ProjManagerId%'
Then dbo.ufn_GetUserForHistoryReport (PerformedDate, SarId, '%ProjManagerId%')
Else
--when Details like '%UserId%'
dbo.ufn_GetUserForHistoryReport (PerformedDate, SarId, '%UserId%')
--(select 'no user') as [AssignedUser]
End as [AssignedUser]
--,dbo.ufn_GetPMForHistoryReport(PerformedDate, SarId) as [AssignedUser]
FROM #history
ORDER BY 1, 2, 3, 4, 5
DROP TABLE #Historyw
Here is the function I believe is causing problems:
ALTER FUNCTION [dbo].[ufn_SarHistoryActionText]
(
-- Add the parameters for the function here
#sarID int
, #status varchar(6)
, #statusDate datetime
)
RETURNS varchar(100)
AS
BEGIN
-- Declare the return variable here
DECLARE #Result varchar(100)
set #Result = (
SELECT C.ActionText
from LuStatusChange as C
WHERE C.FromStatus = dbo.ufn_SarHistoryPriorStatus(#sarID,#status,#statusDate)
AND C.ToStatus = #status
)
-- Return the result of the function
RETURN #Result
END
GO
As I debug and walk through loads of values, I haven't come across anything that resulted in multiple values. maybe I'm missing something.
Add TOP 1 in the select inside the function:
SELECT TOP 1 C.ActionText
Can you replace
set #Result = (
SELECT C.ActionText
from LuStatusChange as C
WHERE C.FromStatus = dbo.ufn_SarHistoryPriorStatus(#sarID,#status,#statusDate)
AND C.ToStatus = #status
)
as below:
#Result ***IN*** (
SELECT C.ActionText
from LuStatusChange as C
WHERE C.FromStatus = dbo.ufn_SarHistoryPriorStatus(#sarID,#status,#statusDate)
AND C.ToStatus = #status
)
If functionally your query should not written more than 1 row, something is wrong with your query.
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.
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
I am new to SQL stored procedures. I need to write a SQL to check a email exists in multiple tables. If a email contains in First Table it returns true and should not execute the rest. Like wise if not I need to check the second table and if i found return true. Finally if i found in last Table I need to return true and else i need to return false.
I am stuck in achieving this. I tried like this. Gives me syntax errors. Please share me a solution for this.
USE Users_UserDetials;
GO
CREATE PROCEDURE Users.GetUserPermissions
#userEmail nvarchar(50),
#areaId nvarchar(10),
#villageCode nvarchar(10)
AS
SET NOCOUNT ON;
IF EXISTS (SELECT 1 FROM Users.GlobalUsers AS GU
WHERE GU.UserEmail = #userEmail)
ELSE
IF EXISTS (SELECT 1 FROM Users.AreaSpecificUsers AS AU
WHERE AU.UserEmail = #userEmail)
ELSE
IF EXISTS (SELECT 1 FROM Users.VillageSpecificUsers AS VU
WHERE VU.UserEmail = #userEmail)
ELSE
'0'
GO
USE Users_UserDetials;
GO
CREATE PROCEDURE Users.GetUserPermissions
#userEmail nvarchar(50),
#areaId nvarchar(10),
#villageCode nvarchar(10)
AS
SET NOCOUNT ON;
IF EXISTS (SELECT 1 FROM Users.GlobalUsers AS GU
WHERE GU.UserEmail = #userEmail)
BEGIN
SELECT 1
END
ELSE
IF EXISTS (SELECT 1 FROM Users.AreaSpecificUsers AS AU
WHERE AU.UserEmail = #userEmail)
BEGIN
SELECT 1
END
ELSE
IF EXISTS (SELECT 1 FROM Users.VillageSpecificUsers AS VU
WHERE VU.UserEmail = #userEmail)
BEGIN
SELECT 1
END
ELSE
BEGIN
SELECT 0
END
END
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.