Stored Function Variables in MySQL - mysql

I am trying to create a stored function in MySQL but when I try to run the function it does't see the variable 'InterimAPI'
Code is as follows:
DELIMITER $$
Create function
InterimAPI_Math(test_subject char(100), grade
int(2), GradeTableValue decimal(5,2))
Returns decimal(6,2) Not Deterministic
Begin
Declare IterimAPI decimal(10,2);
if test_subject = 'Math' AND Grade = 3 THEN
SET ##InterimAPI = (10.9*(GradeTableValue - 253.9)) + 1000;
elseif test_subject = 'MATH' AND GRADE = 4 THEN
SET ##InterimAPI = (10.8*(GradeTableValue -253.4)) + 1000;
elseif test_subject = 'MATH' AND GRDE = 5 THEN
SET ##InterimAPI = (10.1*(GradeTableValue - 250.3)) + 1000;
elseif test_subject = 'MATH' AND GRADE = 6 THEN
SET ##InterimAPI = (9.4*(GradeTableValue - 246.3)) + 1000;
elseif test_subject = 'MATH' AND GRADE = 7 THEN
SET ##InterimAPI = (8.4*(GradeTableValue - 240.2)) + 1000;
elseif test_subject = 'MATH' AND GRADE = 8 THEN
SET ##InterimAPI = (8.4*(GradeTableValue - 239.8)) + 1000;
elseif test_subject = 'Algebra I' AND GRADE = 'EOI' THEN
SET InterimAPI = (17.4*(GradeTableValue - 71.2)) + 1000;
END IF;
Return (InterimAPI);
END
Also slightly confused as to what belongs in the parameters. Is it the information from the table that you want input into the function or something else?

Related

MySQL pass a variable string argument to stored procedure variable

I have the following stored procedure:
CREATE DEFINER=`sleuser`#`%` PROCEDURE `PCDD`(
in ProjectID int,
in MonthName varchar(50),
in ServiceCode varchar(50),
in ProjectName varchar(50)
)
BEGIN
SET #PCProjID = ProjectID;
SET #PCSN1 = "020." + ServiceCode + ".000";
SET #Month = MonthName;
SET #ImpCostID = ProjectName;
SET #ImpCostTask1 = "020." + ServiceCode + ".000";
SELECT
project.project_id,
'FP' as Phase,
ImportCost.OriginalCommitments,
ImportCost.ApprovedCommitmentChanges,
sum(RegisteredChangeOrders) + sum(OriginalContractPrice) as CurrentAssigned,
sum(ProjectCostBudget.PendingChangeOrders) as PendingScopeChanges,
FROM `RCLY-DEV`.ProjectCostBudget
inner join project on project.project_id =
ProjectCostBudget.ProjectID
inner join ImportCost on ImportCost.ProjectID = project.pmis
where ImportCost.ProjectID = #ImpCostID and
ImportCost.Task = #PCSN1 and
ProjectCostBudget.ProjectID = #PCProjID and
ProjectCostBudget.ServiceNumber = #ImpCostTask1
which i call using:
call PCDD(2,'September%2018','0000','RLCY-BB-01')
Where '0000' needs to vary from '0000' to '6000'. When I run the SP for '0000' it returns the expected results, but when I change it to anything else it just returns all nulls. I tried updating #PCSN1 and #ImpCostTask1 to:
SET #PCSN1 = ("020.", ServiceCode, ".000");
SET #ImpCostTask1 = ("020.", ServiceCode, ".000");
But i get the error
"Operand should contain 1 column(s).
What am i doing wrong here? Why does it work for one ServiceCode but not the others?
You need to use ' enqoute string literal and CONCAT instead of '+' for string concatenation:
SET #PCSN1 = "020." + ServiceCode + ".000";
=>
SET #PCSN1 = CONCAT('020.', ServiceCode, '.000');
Same for:
SET #ImpCostTask1 = "020." + ServiceCode + ".000";
=>
SET #ImpCostTask1 = CONCAT('020.', ServiceCode, '.000');

Error 1111 when calling a stored function

So I found a post that talked about putting certain logic tests behind HAVING instead of WHERE. What am I missing that's still tripping error 1111?
DROP PROCEDURE IF EXISTS ELO;
DELIMITER //
CREATE PROCEDURE ELO()
BEGIN
-- declares...
label1: WHILE xGame <= max(games.game_id) DO
SELECT games.game_id, games.game_type, games.date, games.home_team, games.away_team, games.runs0, games.runs1
FROM games
WHERE games.game_id = xGame
HAVING (games.game_type = 0 OR games.game_type = 3)
INTO #id, #ty, #d, #home, #away, #homeR, #awayR;
SET startHomeELO = (SELECT team_elo.team_id, team_elo.date, team_elo.elo FROM team_elo WHERE team_id = home HAVING min(d - team_elo.date));
SET startAwayELO = (SELECT team_elo.team_id, team_elo.date, team_elo.elo FROM team_elo WHERE team_id = away HAVING min(d - team_elo.date));
SET eloDiff = abs((startHomeELO + 25) - startAwayELO);
SET homeELO = (startHomeELO + (40*power(runDiff, (1/3)) * (homeWin - (1/(power(10, (eloDiff/400)) + 1)))));
SET awayELO = (startAwayELO + (40*power(runDiff, (1/3)) * (awayWin - (1/(power(10, (eloDiff/400)) + 1)))));
INSERT INTO team_elo (team_id, game_id, date, elo) VALUES (home, id, d, homeELO);
INSERT INTO team_elo (team_id, game_id, date, elo) VALUES (away, id, d, awayELO);
SET xGame = xGame + 1;
END WHILE label1;
END; //
CALL ELO();
You need to do a separate query to get the maximum ID:
INT maxId;
SELECT MAX(game_id) INTO maxId
FROM games;
label1: while xGame <= maxId DO
...
END WHILE label1;

SQLTransaction2 : Operation cannot be performed on an active transaction FreePascal - Code Typhon

I would like some help solving this error message.
I am using Code Typhon32 V4.9 on Windows 7 Pro.
I had a project connecting to a firebird database,
Single form which works fine- No problems.
I added a 2nd form to be my data entry form linked to another Database in
Firebird - I need both databases in one project.
Since adding the 2nd form I am getting the following error when I close code typhon and when I close Form1 while using the debugger: "SQLTransaction2 : Operation cannot be performed on an active transaction"
I have tried numerous of solution found on the internet but can not solve it.
I have a button that open the 2nd from as Follows:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
frmContributions := TfrmContributions.Create(nil);
try
frmContributions.ShowModal;
finally
frmContributions.Free;
end;
end;
Here is my 2nd form Code:
unit uFirebirdDemo1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, sqldb, IBConnection, pqconnection, db, FileUtil, Forms,
Controls, Graphics, Dialogs, StdCtrls, DBGrids, DbCtrls;
type
TfrmContributions = class(TForm)
btnUpdate: TButton;
btnDeleteProgrammer: TButton;
dsProgrammer: TDatasource;
dbgrdProgrammer: TDBGrid;
dbnavProgrammer: TDBNavigator;
IBConnection2: TIBConnection;
sqlqProgrammer: TSQLQuery;
SQLScript1: TSQLScript;
SQLTransaction2: TSQLTransaction;
procedure btnDeleteProgramClick(Sender: TObject);
procedure btnUpdateClick(Sender: TObject);
procedure btnUpdateProgramsClick(Sender: TObject);
procedure btnDeleteProgrammerClick(Sender: TObject);
procedure dbgrdCombinedTitleClick(Column: TColumn);
procedure dbgrdProgrammerTitleClick(Column: TColumn);
procedure dbgrdProgramsTitleClick(Column: TColumn);
procedure edtSearchChange(Sender: TObject);
procedure Savechanges;
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
end;
var
frmContributions: TfrmContributions;
implementation
{$R *.lfm}
procedure TfrmContributions.btnUpdateClick(Sender: TObject);
begin
sqlqProgrammer.Edit;
sqlqProgrammer.Post;
sqlqProgrammer.ApplyUpdates(1);
SQLTransaction2.CommitRetaining;
end;
procedure TfrmContributions.btnDeleteProgrammerClick(Sender: TObject);
begin
SQLScript1.Script.Text:= 'Delete from Programmer WHERE ID = ' + dbgrdProgrammer.Columns[0].Field.AsString + ';';
SQLScript1.Execute;
SQLTransaction2.CommitRetaining;
sqlqProgrammer.Refresh;
end;
procedure TfrmContributions.dbgrdProgrammerTitleClick(Column: TColumn);
begin
sqlqProgrammer.Close;
SQLTransaction2.Active := TRUE;
sqlqProgrammer.SQL.Text := 'Select * from Programmer ORDER BY ID DESC';
sqlqProgrammer.Open;
end;
procedure TfrmContributions.Savechanges;
// Saves edits done by user, if any.
begin
try
if SQLTransaction2.Active then
// Only if we are within a started transaction
// otherwise you get "Operation cannot be performed on an inactive dataset"
begin
sqlqProgrammer.ApplyUpdates; //Pass user-generated changes back to database...
SQLTransaction2.Commit; //... and commit them using the transaction.
//SQLTransaction2.Active now is false
end;
except
on E: EDatabaseError do
begin
MessageDlg('Error', 'A database error has occurred. Technical error message: ' +
E.Message, mtError, [mbOK], 0);
end;
end;
end;
procedure TfrmContributions.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
SaveChanges;
sqlqProgrammer.Close;
SQLTransaction2.Commit;
SQLTransaction2.RollBack;
SQLTransaction2.Active := False;
IBConnection2.Connected := False;
end;
end.
I tried adding a formclose to my first form as follows in order to solved the problem
but it does not seem to be doing anything:
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
frmContributions.SaveChanges;
frmContributions.SQLTransaction2.RollBack;
frmContributions.SQLTransaction2.Active := False;
frmContributions.IBConnection2.Connected := False;
end;
I have tried different solutions found on the internet but I am still getting:
"SQLTransaction2 : Operation cannot be performed on an active transaction" when i
close my project using the debugger, and also I get the same error when closing down
code typhon.
Here is the lfm file:
object frmContributions: TfrmContributions
Left = 816
Height = 415
Top = 172
Width = 774
Caption = 'Data Entry for Promo'
ClientHeight = 415
ClientWidth = 774
Color = clHighlight
OnClose = FormClose
LCLVersion = '1.3'
object btnUpdate: TButton
Left = 536
Height = 25
Top = 376
Width = 168
Caption = 'Update programmers'
OnClick = btnUpdateClick
TabOrder = 0
end
object dbgrdProgrammer: TDBGrid
Left = 16
Height = 360
Top = 0
Width = 744
Color = clWindow
Columns = <
item
Title.Caption = 'ID'
Width = 60
FieldName = 'ID'
end
item
Title.Caption = 'DATESENT'
FieldName = 'DATESENT'
end
item
Title.Caption = 'COURSE'
Width = 140
FieldName = 'COURSE'
end
item
Title.Caption = 'PROMOTYPE'
Width = 140
FieldName = 'PROMOTYPE'
end
item
Title.Caption = 'LINK'
Width = 100
FieldName = 'LINK'
end
item
Title.Caption = 'VALUE'
Width = 50
FieldName = 'VALUECHART'
end
item
Title.Caption = 'TOTALSENT'
FieldName = 'TOTALSENT'
end
item
Title.Caption = 'NOTES'
FieldName = 'NOTES'
end>
DataSource = dsProgrammer
TabOrder = 1
OnTitleClick = dbgrdProgrammerTitleClick
end
object dbnavProgrammer: TDBNavigator
Left = 280
Height = 25
Top = 376
Width = 241
BevelOuter = bvNone
ChildSizing.EnlargeHorizontal = crsScaleChilds
ChildSizing.EnlargeVertical = crsScaleChilds
ChildSizing.ShrinkHorizontal = crsScaleChilds
ChildSizing.ShrinkVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 100
ClientHeight = 25
ClientWidth = 241
DataSource = dsProgrammer
Options = []
TabOrder = 2
VisibleButtons = [nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbRefresh]
end
object btnDeleteProgrammer: TButton
Left = 64
Height = 25
Top = 376
Width = 201
Caption = 'Delete Selected Programmer'
OnClick = btnDeleteProgrammerClick
TabOrder = 3
end
object dsProgrammer: TDataSource
DataSet = sqlqProgrammer
left = 696
top = 168
end
object IBConnection2: TIBConnection
Connected = True
LoginPrompt = False
DatabaseName = '.......CONTRIBUTIONS.FDB'
KeepConnection = False
Password = 'password'
Transaction = SQLTransaction2
UserName = 'username'
HostName = 'hostname'
left = 696
top = 8
end
object SQLTransaction2: TSQLTransaction
Active = True
Action = caCommitRetaining
Database = IBConnection2
left = 696
top = 56
end
object sqlqProgrammer: TSQLQuery
IndexName = 'DEFAULT_ORDER'
FieldDefs = <
item
Name = 'ID'
DataType = ftInteger
Precision = -1
Size = 0
end
item
Name = 'DATESENT'
DataType = ftDate
Precision = -1
Size = 0
end
item
Name = 'PROMOTYPE'
DataType = ftString
Precision = -1
Size = 25
end
item
Name = 'COURSE'
DataType = ftString
Precision = -1
Size = 25
end
item
Name = 'LINK'
DataType = ftString
Precision = -1
Size = 450
end
item
Name = 'VALUECHART'
DataType = ftInteger
Precision = -1
Size = 0
end>
Active = True
Database = IBConnection2
Transaction = SQLTransaction2
SQL.Strings = (
'select * from Programmer order by ID DESC'
)
UpdateSQL.Strings = (
''
)
InsertSQL.Strings = (
''
)
DeleteSQL.Strings = (
''
)
Params = <>
UpdateMode = upWhereChanged
UsePrimaryKeyAsKey = False
left = 696
top = 224
end
object SQLScript1: TSQLScript
DataBase = IBConnection2
Transaction = SQLTransaction2
Directives.Strings = (
'SET TERM'
'COMMIT'
'#IFDEF'
'#IFNDEF'
'#ELSE'
'#ENDIF'
'#DEFINE'
'#UNDEF'
'#UNDEFINE'
)
Script.Strings = (
''
)
Terminator = ';'
CommentsinSQL = True
UseSetTerm = True
UseCommit = True
UseDefines = True
left = 696
top = 112
end
end
Thank you.
Actually I don't know exactly what should be next, but
(0) I'd move the database code into standalone TDataModule (outside the UI code) to make the code more straightforward to read and maintain. During this refactoring you may spot a hidden problem..
(1) this http://forum.lazarus.freepascal.org/index.php?topic=14301.0 seems to solve similar problem
(2) book Lazarus, the complete guide seems to have a chapter about TDataModule
(3) Martin Fowler wrote a book about refactoring and runs a site about the same at http://refactoring.com/
(4) some components don't behave well if they are active in the design mode. As it is actually different and more complicated scenario (lots of ifs with csDesigning in ComponentState, sequence diagram of events is different, nearly random and everything should be foolproof and re-entrant..). So safe side for production is to turn component's active state off in the design mode and activate them in code in a well defined order anticipated by the component authors
(5) If you experience the error only when in the debugger and it does not appear in production code I think that you can ignore the problem as the debugging environment is <see="(4)">

error message not displaying on mysql stored procedure

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;

MySQL Stored Procedure with IF/THEN/ELSE

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