I am trying to validate something but It always returns a success result. I wonder what's wrong with my codes.
INSERT INTO playlist_details (playlist_id,filename,image_id,transition,timeframe,userid,update_date)
VALUES (i_playlistid,i_filename,i_imageid, i_transition, i_time, i_userid,i_date);
SELECT booking_id INTO v_booking_id FROM staging_table WHERE playlist_id = i_playlistid LIMIT 1;
SELECT num_of_spots INTO v_spots FROM booking_sum WHERE booking_id = v_booking_id;
SET v_allowed_time = v_spots * 30;
IF ((SELECT SUM(timeframe) FROM playlist_details WHERE playlist_id = i_playlistid) > v_allowed_time) THEN
SET o_success = FALSE;
SET o_message = 'You exceeded the time allowed with your booking';
SELECT playlist_id,filename,image_id,transition,timeframe,userid FROM playlist_details
WHERE userid = i_userid;
ELSE
SELECT playlist_id,filename,image_id,transition,timeframe,userid FROM playlist_details
WHERE userid = i_userid;
SET o_success = TRUE;
SET o_message = 'Success';
END IF;
Related
I am using function to update to one column , like
DetailedStatus = dbo.fn_GetProcessStageWiseStatus(PR.ProcessID, PR.ProcessRunID, getdate())
Here 500,000 records are continuously UPDATED in this line. Its like like a loop
So using this function for few records its executing fast but when its 500,000 records executing it becomes very slow...
What can I do to make this execute faster using many records?
Any measures to be taken or any split to be used?
Function:
CREATE FUNCTION [dbo].[fn_GetProcessStageWiseStatus]
(
#ProcessID INT
,#ProcessRunID INT
,#SearchDate SMALLDATETIME
)
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE
#iLoopCount SMALLINT
,#iRowCount SMALLINT
,#StepProgress VARCHAR(100)
,#StepCount SMALLINT
IF EXISTS(
SELECT TOP 1 1
FROM dbo.Step S WITH(NOLOCK)
JOIN dbo.vw_FileGroup FG
ON S.FileConfigGroupID = FG.FileConfigGroupID
WHERE S.ProcessID = #ProcessID
AND S.Active = 1
AND FG.FileConfigGroupActive = 1
AND FG.Direction = 'Inbound'
)
BEGIN
SET #StepProgress = 'Not Received'
END
ELSE
BEGIN
SET #StepProgress = 'Not Started'
END
DECLARE #StepRunDetailsTable TABLE
(
KeyNo INT IDENTITY(1,1)
,StepID INT
,StepStartTime SMALLDATETIME
,StepEndTime SMALLDATETIME
,SourceEnv VARCHAR(100)
,DestEnv VARCHAR(100)
)
INSERT INTO #StepRunDetailsTable
SELECT
S.StepID
,MAX(isnull(SR.StepStartTime, '06/06/2079'))
,MAX(isnull(SR.StepEndTime, '06/06/2079'))
,isnull(SENV.EnvironmentName, '')
,isnull(DENV.EnvironmentName, '')
FROM dbo.ProcessRun PR WITH(NOLOCK)
JOIN dbo.StepRun SR WITH(NOLOCK)
ON SR.ProcessRunID = PR.ProcessRunID
JOIN dbo.vw_StepHierarchy SH
ON SR.StepID = SH.StepID
AND SH.Active = 1
JOIN dbo.Step S WITH(NOLOCK)
ON SH.StepID = S.StepID
JOIN dbo.WorkFlow WF WITH(NOLOCK)
ON S.WorkFlowID = WF.WorkFlowID
AND WF.Active = 1
JOIN dbo.Environment SENV WITH(NOLOCK)
ON SENV.EnvironmentID = WF.SourceEnvironmentID
AND SENV.Active = 1
JOIN dbo.Environment DENV WITH(NOLOCK)
ON DENV.EnvironmentID = WF.DestinationEnvironmentID
AND DENV.Active = 1
WHERE PR.ProcessRunID = #ProcessRunID
GROUP BY S.StepID, SENV.EnvironmentName, DENV.EnvironmentName, SH.StepOrder
ORDER BY SH.StepOrder ASC
SELECT #StepCount = COUNT(*)
FROM dbo.ProcessRun PR WITH(NOLOCK)
JOIN dbo.Step S WITH(NOLOCK)
ON PR.ProcessID = S.ProcessID
AND PR.ProcessRunID = #ProcessRunID
AND S.Active = 1
SELECT #iRowCount = COUNT(DISTINCT StepID) FROM #StepRunDetailsTable
SET #iLoopCount = 0
WHILE (#iRowCount > #iLoopCount)
BEGIN
SET #iLoopCount = #iLoopCount + 1
SELECT
#StepProgress =
CASE
--WHEN #SearchDate BETWEEN StepStartTime AND StepEndTime
WHEN #SearchDate >= StepStartTime AND #SearchDate <= StepEndTime
THEN DestEnv + ' Load in Progress'
WHEN #SearchDate > StepEndTime AND #iLoopCount < #StepCount
THEN 'Waiting on next step - Loaded to ' + DestEnv
WHEN #SearchDate > StepEndTime AND #iLoopCount = #StepCount
THEN 'Completed'
WHEN #SearchDate < StepStartTime AND #iLoopCount = 1
THEN 'Load Not Started'
ELSE #StepProgress
END
FROM #StepRunDetailsTable
WHERE KeyNo = #iLoopCount
END
RETURN #StepProgress
END
Thanks in advance.
Seems like you have a change in execution plan when you try to update 500k rows.
You can try and set forceseek hint on the from clause to force using seeks instead of scans.
Also, WHILE (#iRowCount > #iLoopCount) should be replaced with if exists, because you basically check for certain conditions on the results table and you need to return as early as possible.
I see that you use nolock hint everywhere to allow dirty reads, you can set isolation level read uncommitted in the calling stored procedure and remove all of those; or consider to change the database to set read_committed_snapshot on to avoid locks.
By the way, scalar function calls in SQL Server are very expensive, so if you have some massive updates/selects happening in a loop where you call a function you have to avoid using functions as much as possible.
exactly I want to write "UPDATE" and "SELECT" into one query.
I need check for setting a field.
for this action, I used SELECT query on TABLE1 and then if it dose not have result, another filed of TABLE2 is updated.
FOR EX:
$res = mysqli_query($con , "select sID FROM schedule where (dayID = '{$this->dID}' AND patientID = '')");
$rep = mysqli_fetch_array($res);
if(count($rep) == 0)
mysqli_query($con,"update days set schFilled = 1 where dID = '{$this->dID}'");
else
mysqli_query($con,"update days set schFilled = 0 where dID = '{$this->dID}'");
I would like run those with ONE query, in fact I want something like this:(whit CASE to write second update too)
update days set schFilled = 0 where( (select sID FROM schedule where (dayID = '{$this->dID}' AND patientID = '') IS NULL) AND (dID = '{$this->dID}'))
use the mysqli object like this:
$res = mysqli_query($con , "your select");
if($res->num_rows === 0) {
//no res
}
else {
//else
}
"UPDATE days SET schFilled =
CASE
WHEN (SELECT IF(EXISTS(select sID FROM schedule where (dayID = '{$this->dID}' AND patientID = '' AND hour != 0)), 1, 0))
THEN 0
ELSE 1
END
where dID = '{$this->dID}'"
I'm trying to recreate some code I did in SQL server on mySQL. I want to insert a row for every row in a table. I am using a loop to do this, in SQL server I used SELECT TOP #foo
here is my mySQl
begin
set #maxloop = (select max(id) from `LeagueInfo`);
set #loopno = 1;
while #loopno <= #maxloop DO
SET #mtop = (select `teams` * `homegames` from `LeagueInfo` where id = #loopno);
SET #div = (select `LeagueShortName` from `LeagueInfo` where id = #loopno);
SET #teams = (select teams from `LeagueInfo` where id = #loopno);
SET #homegames = (select homegames from `LeagueInfo` where id = #loopno);
SET #fthgsum = (select sum(`FTHG`)/#teams/#homegames from `footy` where `id` in(select`id`, `div` from `footy`
where `div` = #DIV
order by `matchdate` desc LIMIT #mtop));
SET #ftagsum = (select sum(`FTAG`)/#teams/#homegames from `footy` where `id` in(select`id`, `div` from `footy`
where `div` = #DIV
order by `matchdate` desc LIMIT #mtop));
insert into `looptable` (`di`, `homeav`, `awayav`) values (#div, #fthgsum,#fthgsum);
set #loopno = #loopno +1;
END while;
END;
I get an error on limit #mtop. I've read that I can get round this with a prepared statement but I'm not sure how to do it in a subquery. Is there a was to do this or is there another was I can select the top x amount of rows based on a value in another table for each row in that table.
Thanks
Paul
In your line of code,
SET #mtop = (select 'teams' * 'homegames' from 'LeagueInfo' where id = #loopno)
mtop is not a number, which is false since limit needs to be a number.
maybe you want to use "count(*)"?
I have a flag in my database called published, I set this to 1 for a published row. My question is , is there a way to set all other rows to 0 and set a particular row to 1 with just one query.
At the moment im using:
$db->query("UPDATE my_table SET published = '0'");
$db->query("UPDATE my_table SET published = '1' WHERE id = '$id'");
UPDATE my_table SET published = IF (id = $id,1,0);
Use a CASE Statement
UPDATE my_table
SET published = CASE
WHEN id = '$id' THEN 1
ELSE 0 END
In MySQL, there's no boolean type (conditions return an integer), so this works too :
UPDATE my_table
SET published = (id = $id);
id = $id returns 0 if $id is different than id, else 1.
I have a MySQL stored procedure and in it, the following WHILE statement.
I have confirmed that #RowCnt is 1, and #MaxRows is 6090, however after further debugging, I realized that the WHILE statement is going through a single iteration and not continuing; so I'm hoping to have some light shed on what could possibly be causing this.
Full disclosure: I ported this from SQL Server to a MySQL stored procedure, something I have never taken on before. (meaning SQL Server, porting OR stored procedures..)
WHILE #RowCnt <= #MaxRows DO
SELECT #currentReadSeq:=ReadSeq, #currentReadStrength:=ReadStrength, #currentReadDateTime:=ReadDateTime, #currentReaderID:=ReaderID FROM tblTempRead WHERE rownum = #RowCnt;
IF ( ((#lastReadSeq + 10) > #currentReadSeq) AND (#lastReaderId = #currentReaderId) ) THEN
SET #lastReadSeq = #currentReadSeq, #lastReadStrength = #currentReadStrength, #lastReadDateTime = #currentReadDateTime, #lastReaderID = #currentReaderID;
ELSE
INSERT INTO tblreaddataresults (SiteID, ReadDateTimeStart, ReadDateTimeEnd, ReadSeqStart, ReadSeqEnd, ReaderID, DirectSeconds) VALUES ('1002', #saveReadDateTime, #lastReadDateTime, #saveReadSeq, #lastReadSeq, #lastReaderID, timestampdiff(SECOND,#saveReadDateTime,#lastReadDateTime));
SET #saveReadSeq = #currentReadSeq, #saveReadStrength = #currentReadStrength, #saveReadDateTime = #currentReadDateTime, #saveReaderID = #currentReaderID;
SET #lastReadSeq = #saveReadSeq, #lastReadStrength = #saveReadStrength, #lastReadDateTime = #saveReadDateTime, #lastReaderID = #saveReaderID;
END IF;
SET #RowCnt = #RowCnt+1;
END WHILE;
Try This Construct
WHILE (#RowCnt <= #MaxRows)
BEGIN
SELECT #currentReadSeq:=ReadSeq, #currentReadStrength:=ReadStrength, #currentReadDateTime:=ReadDateTime, #currentReaderID:=ReaderID FROM tblTempRead WHERE rownum = #RowCnt;
IF (((#lastReadSeq + 10) > #currentReadSeq) AND (#lastReaderId = #currentReaderId))
BEGIN
SET #lastReadSeq = #currentReadSeq, #lastReadStrength = #currentReadStrength, #lastReadDateTime = #currentReadDateTime, #lastReaderID = #currentReaderID;
END
ELSE
BEGIN
INSERT INTO tblreaddataresults (SiteID, ReadDateTimeStart, ReadDateTimeEnd,ReadSeqStart, ReadSeqEnd, ReaderID, DirectSeconds) VALUES ('1002',#saveReadDateTime, #lastReadDateTime, #saveReadSeq, #lastReadSeq, #lastReaderID,timestampdiff(SECOND,#saveReadDateTime,#lastReadDateTime));
SET #saveReadSeq = #currentReadSeq, #saveReadStrength = #currentReadStrength, #saveReadDateTime = #currentReadDateTime, #saveReaderID = #currentReaderID;
SET #lastReadSeq = #saveReadSeq, #lastReadStrength = #saveReadStrength,#lastReadDateTime = #saveReadDateTime, #lastReaderID = #saveReaderID;
END
SET #RowCnt = #RowCnt+1;
END