Using SELECT resultset to run UPDATE query with MySQL Stored Procedures - sql

I'm trying to understand MySQL Stored Procedures, I want to check if a users login credentials are valid and if so, update the users online status:
-- DROP PROCEDURE IF EXISTS checkUser;
DELIMITER //
CREATE PROCEDURE checkUser(IN in_email VARCHAR(80), IN in_password VARCHAR(50))
BEGIN
SELECT id, name FROM users WHERE email = in_email AND password = in_password LIMIT 1;
-- If result is 1, UPDATE users SET online = 1 WHERE id = "result_id";
END //
DELIMITER ;
How Can I make this if-statement based on the resultsets number of rows == 1 or id IS NOT NULL?

DELIMITER //
CREATE PROCEDURE checkUser(IN in_email VARCHAR(80), IN in_password VARCHAR(50))
BEGIN
DECLARE tempId INT DEFAULT 0;
DECLARE tempName VARCHAR(50) DEFAULT NULL;
DECLARE done INT DEFAULT 0;
DECLARE cur CURSOR FOR
SELECT id, name FROM users WHERE email = in_email AND password = in_password;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur;
REPEAT
FETCH cur INTO tempId, tempName;
UPDATE users SET online = 1 WHERE id = tempId;
UNTIL done = 1 END REPEAT;
CLOSE cur;
SELECT tempName;
END //
DELIMITER ;
NB: I have not tested this. It's possible that MySQL doesn't like UPDATE against a table it currently has a cursor open for.
PS: You should reconsider how you're storing passwords.
Re comment about RETURN vs. OUT vs. result set:
RETURN is used only in stored functions, not stored procedures. Stored functions are used when you want to call the routine within another SQL expression.
SELECT LCASE( checkUserFunc(?, ?) );
You can use an OUT parameter, but you have to declare a user variable first to pass as that parameter. And then you have to select that user variable to get its value anyway.
SET #outparam = null;
CALL checkUser(?, ?, #outparam);
SELECT #outparam;
When returning result sets from a stored procedure, it's easiest to use a SELECT query.

Use:
UPDATE USERS
SET online = 1
WHERE EXISTS(SELECT NULL
FROM USERS t
WHERE t.email = IN_EMAIL
AND t.password = IN_PASSWORD
AND t.id = id)
AND id = 'result_id'
Why do you have LIMIT 1 on your SELECT? Do you really expect an email and password to be in the db more than once?

You could try an if statement if you have an result which returns 1
i looked at yor code, it seems nothing returns a true so you have to refactor it,
as above omg wrote thats realy true why do you have an limit 1 in your select query where only one emailadress can exisst?
something like this
update users set if(result==1,online=1,online=0) where email=emailadress

Related

Sql Server make stored proc show select and run other proc on select's results

I need to make a stored procedure that will be called form a web method. The basic idea is the proc needs to
Check if there will be a result to the query (IF EXISTS ...)
If there is a result, return one row with an ID value the webmethod
will use
Call another stored proc using that same ID as a
parameter (this proc will then update the record the first proc took
the ID from and increase the value of one of it's column's).
So far I have
CREATE PROC Sponsors.GetLightBoxAds (#SponsorID varchar(30))
AS
BEGIN
IF EXISTS (SELECT TOP 1
AD.ADID
FROM Sponsors.AD
WHERE AD.Active = 1 and AD.Sponsor = #SponsorID)
--takes the ID value of first active AD record it finds, at random, for that sponsor
BEGIN
SELECT TOP 1
AD.ADID --I want to use this value as my parameter for the second proc.
FROM Sponsors.AD
WHERE AD.Active = 1
ORDER BY newid()
--Ideally I'd like to call a separate proc here because there's more to be done
--but for testing I'm trying to run the update here
UPDATE Sponsor.AD
SET AD.CurrentClickCount = AD.CurrentClickCount + 1
WHERE ADID = #ADID -- use the result of the first select here.
END
END
GO
Is there a way to make the proc both return the ID I wanted and call another proc using that ID as the call's parameter?
I could split this into separate calls and let the web backend handle the parameter calls but this adds latency and there are possible concurrency issues if this latency becomes large so I prefer to have the server run both calls asap.
As stated above, you would first need to declare #ADID - something like:
DECLARE #ADID INT;
Once you've done that, select the ID you want into it:
SELECT TOP 1 #ADID = AD.ADID
FROM Sponsors.AD
WHERE AD.Active = 1 and AD.Sponsor = #SponsorID
Then you can conditionally start your process:
IF ISNULL(#ADID,-1) != -1
BEGIN
EXEC YourStoredProc #ADID
END
To return the ID at the end, just do:
SELECT #ADID AS ADID;
You could instead use the output parameter method by declaring the output variable with your procedure:
CREATE PROC Sponsors.GetLightBoxAds (
#SponsorID varchar(30),
#ADIDOut INT OUTPUT
)
AS --...
Then do:
SELECT #ADIDOut = #ADID;

Need to wait on specific column state change in SQL

I need to check for the status change of a certain column in the table
I can do it using while loop, where i can get the column value and check the value and break from the loop if value is changed.
i am using SQL server 2008.
is there a better way?
Here is the sample sql query
declare #status int = 1
select #status = status from MyTable with (nolock) where Id = 100034
while #status <> 3
begin
WAITFOR DELAY '00:01'
select #status = status from MyTable with (nolock) where Id = 100034
end
Have you considered to use a trigger instead of an stored procedure? This is exactly, what are triggers for.
CREATE TRIGGER reactOnStatus3
ON MyTable
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
IF Status = 3
EXEC DoTheMagicStoredProcedure;
END;

SQL Server : get the row Identity

I have this as the first part of a stored procedure:
DECLARE #_id as int
if exists(select 1 from JTrack_Visitors WHERE cookie = #cookie)
begin
UPDATE JTrack_Visitors
SET LastSeen = #_now
WHERE cookie = #cookie
end
else
begin
INSERT INTO JTrack_Visitors(Cookie, CreatedOn, LastSeen)
VALUES (#cookie, #_now, #_now)
end
How can I set #_id to be the identity of the row either being inserted or updated? I need that value to use later in the stored procedure.
Thanks.
You can make use of OUTPUT clause in your both statements, in either case populate a table variable and later retrieve value from that table variable.
DECLARE #_id as int;
DECLARE #ID_Table TABLE(ID INT);
IF EXISTS (select 1 from JTrack_Visitors WHERE cookie = #cookie)
BEGIN
UPDATE JTrack_Visitors
SET LastSeen = #_now
OUTPUT inserted.ID INTO #ID_Table(ID)
WHERE cookie = #cookie
END
ELSE
BEGIN
INSERT INTO JTrack_Visitors(Cookie,CreatedOn,LastSeen)
OUTPUT inserted.ID INTO #ID_Table(ID)
VALUES (#cookie,#_now,#_now)
END
SELECT #_id = ID FROM #ID_Table;
Depending on the SQL Server version you're using you could use the MERGE statement including the OUTPUT clause to get the values you're looking for.
This would also eliminate the need to check for existence and either update or insert.

find a number that is not in the ID column

Table has two columns Name and ID.
ID (int,not null)
Name (nvarchar(255),not null)
I need a SQL script that will run on a report server that will do the following:
User inputs "New.Name"
User inputs "Old.Name"
If "New.Name" AND "Old.Name" is not in Column [Name] then Print "Names Incorrect"
then return to beginning. else continue
Find a number that is not in the ID Column then Declare as #Number
Declare #NewID AS int
Declare #OldID AS int
SET #NewID = ID Where Name = New.Name
SET #OldID = ID where Name = Old.Name
UPDATE Table SET ID = #Number WHERE ID = #NewID
UPDATE Table SET ID = #NewID WHERE ID = #OldID
UPDATE Table SET ID = #OldID WHERE ID = #NewID
Is it possible to code this in SQL Server 2005 Reporting Services?
I have tried my best with my little knowledge of SQL but I am not sure what to do with the rest.
Yes. I think this is possible.
SQL Server Reporting Services accepts parameters and can pass these to a stored procedure.
These parameters can also be bound to lists which means that the NewName and OldName parameters could be populated with existing values from the Name column.
The stored procedure would need to return a result set (say with one column called result that you then display on the report)
This isn't a typical use for SSRS though and may well not be the best interface for doing this.

How to deal with Stored Procedure?

Hello I am new in creating stored procedure can you help me how to do this.
Error:
Incorrect syntax near the keyword 'AS'.
Must declare scalar variable #Serial.
CREATE PROCEDURE sp_SIU
-- Add the parameters for the stored procedure here
#Serial varchar(50),
#Part varchar(50),
#Status varchar(50),
AS
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
/*SET NOCOUNT ON;*/
-- Insert statements for procedure here
--where in my form if i enter serial number it will show select values
Select SerialNumber,PartNumber,Status from Table1 where SerialNUmber = #Serial
--Then if is correct it will Update Status on combobox
Update Table1 SET
Status=#Status
where SerialNumber=#SerialNumber
--then Insert Serial Number,Parnumber to Table 2
DECLARE #Count int
select #Count = Count(SerialNumber) from Table1 WHERE SerialNumber = #Serial
IF #Count = 0
BEGIN
INSERT INTO Table2 (SerialNumber,PArtNumber)
VALUES
(#Serial, #Part)
END
RETURN #Count
RETURN
Edit: Moved Updated info posted as an answer into Question
Oops my post is not that kind a miss.
It is possible to join this 3 sql string in one stored procedure?
Scenario:
{
What i have to do in my form is that i will enter serial number to txtserial.text by using the select sql it will show serialnumber,partnumber and status on lblserial.text,lblpartnumber.text and lblstatus.text.
And i will compare:
txtserial.text == lblserial.text
txtpartnumber.text == lblpartnumber.text
for my error handler.
{
Select SerialNumber,PartNumber,Status from Table1 where SerialNUmber = #Serial
}
Then if they are equal then:
I will update my Status from cbostatus.text if serial and part is correct then use sql upate.
{
Update Table1 SET
Status=#Status,
Modifiedby=#username,
DateModified=#Date
where SerialNumber=#Serial
}
Then insert serialnumber, using sql insert to another table.
{
INSERT INTO Table2 (SerialNumber,DateCreated,Createdby)
VALUES
(#Serial,#date,#username)
}
something likethis.
")
You have a rogue comma here
#Status varchar(50),
AS
and the name lurches between #Serial and #SerialNumber are these intended to be 2 different parameters?
Also what is the purpose of this line?
Select SerialNumber,PartNumber,Status from Table1 where SerialNUmber = #Serial
Currently it will just send back a 3 column result set to the calling application. Is that what it is intended to do (it doesn't seem to match the following comment which seems to imply it is meant to be some kind of check)?
Yes, you can execute 3 SQL statements inside one stored procedure. You probably want to declare some local variables inside your sproc to hold the intermediate results, i.e.
CREATE PROCEDURE BLAHBLAH
#SerialNumber VarChar(50)
AS
BEGIN
DECLARE #partnumber varchar(50);
SELECT #partnumber = partnumber FROM Table WHERE serialnumber = #SerialNumber;
...
SELECT #partnumber; --- return as recordset
RETURN #partnumber; --- return as return value
END
Then you can later insert #partnumber, test #partnumber, return #partnumber etc. I don't quite understand what you want to do; seems like you mostly want to look up a partnumber based on a serial number, but you want to do some uniqueness tests also. It would help if you could clarify the goal a bit more.
I recommend you ignore the user interface stuff for the moment. Write yourself some nice clean stored procedures that encapsulate the transaction and will do the right thing even if fired off at the same time from two different connections. Get everything working to your satisfaction in your SQL environment. Then go back to the user interface.
Oops my post is not that kind a miss.
It is possible to join this 3 sql string in one stored procedure?
Scenario:
What I have to do in my form is that I will enter serial number to txtserial.text by using the select sql it will show serialnumber,partnumber and status on lblserial.text,lblpartnumber.text and lblstatus.text.
AndI will compare:
txtserial.text == lblserial.text
txtpartnumber.text == lblpartnumber.text
for my error handler.
{
Select SerialNumber,PartNumber,Status from Table1 where SerialNUmber = #Serial
}
Then if they are equal then:
I will update my Status from cbostatus.text if serial and part is correct then use sql update.
{
Update Table1
SET Status = #Status,
Modifiedby = #username,
DateModified = #Date
where SerialNumber = #Serial
}
Then insert serialnumber, using sql insert to another table.
{
INSERT INTO Table2(SerialNumber, DateCreated, Createdby)
VALUES(#Serial, #date, #username)
}
something like this.