MySQL存储过程循环遍历变量并插入临时表
Posted
技术标签:
【中文标题】MySQL存储过程循环遍历变量并插入临时表【英文标题】:MySQL stored procedure loop through variables and insert into temporary table 【发布时间】:2018-08-30 15:35:28 【问题描述】:我有一个存储过程,它运行一个 select 语句,该语句返回一行并将内容插入到临时表中。 select 语句在 where 子句中有 6 个条件语句,我基本上需要遍历 3 组附加条件并将这些结果插入临时表。这是我目前所拥有的:
CREATE DEFINER=`sleuser`@`%` PROCEDURE `CostDashboard`()
BEGIN
create temporary table TempTable (
ProjectID int,
Phase varchar(100),
OriginalCommitments float,
ApprovedCommitmentChanges float,
CurrentAssigned float,
PendingScopeChanges float,
EAC float,
PercentComplete float
);
insert into TempTable(
SELECT project_id,
'FP' as Phase,
OriginalCommitments,
ApprovedCommitmentChanges,
OriginalCommitments+ApprovedCommitmentChanges as CurrentAssigned,
sum(ProjectCostBudget.PendingChangeOrders) as PendingScopeChanges
sum(ProjectCost.CurrentWorkCompleted) +
sum(ProjectCost.EstimateToComplete) as EAC,
(sum(ProjectCost.CurrentWorkCompleted) +
sum(ProjectCost.EstimateToComplete) /
(sum(ProjectCostBudget.OriginalContractPrice +
ProjectCostBudget.RegisteredChangeOrders))) as PercentComplete
FROM `RCLY-DEV`.project
inner join ImportCost on ImportCost.ProjectID = project.pmis
inner join ProjectCostBudget on ProjectCostBudget.ProjectID =
project.project_id
inner join ProjectCost on ProjectCost.ProjectID = project.project_id
where ImportCost.ProjectID = 'RLCY-BB-01'
and ImportCost.Task = "020.0000.000"
and ProjectCostBudget.ProjectID = 2
and ProjectCostBudget.ServiceNumber = "020.0000.000"
and ProjectCost.MonthYear != ''
and ProjectCost.MonthYear like 'July%2018'
);
select * from TempTable
;
END
这可以工作并在 where 子句中插入带有硬编码值的一条记录,但我需要为 3 组变量运行它,所以我创建了一个额外的临时表,如下所示:
|ImpCostID|ImpCostTask |PCBID|PCBServNum |MonthYear|
-----------------------------------------------------
|XXY-01-01|030.0000.000|3 |030.0000.000|July%2018|
|QWY-01-01|040.0000.000|4 |040.0000.000|May%2018 |
|ZXF-01-01|040.0000.000|5 |050.0000.000|June%2018|
但我不确定如何将这些值集分配给变量,然后遍历它们。有什么建议吗?
【问题讨论】:
【参考方案1】:尽可能避免 SQL 语句的序列化(可能代价高昂)。在这种情况下,您可以简单地将 JOIN 与参数表一起用于您的实际查询。如果您只是使用临时表 TempTable
为您保存结果,那么您也不需要这样做,因为您可以在一个查询中获得所有结果:
CREATE DEFINER=`sleuser`@`%` PROCEDURE `CostDashboard`()
BEGIN
create temporary table query_params_tmp (
ImpCostID varchar(20),
ImpCostTask varchar(20),
PCBID int,
PCBServNum varchar(20),
MonthYear varchar(20)
);
insert into query_params_tmp values
('XXY-01-01', '030.0000.000', 3, '030.0000.000', 'July%2018'),
('QWY-01-01', '040.0000.000', 4, '040.0000.000', 'May%2018'),
('ZXF-01-01', '040.0000.000', 5, '050.0000.000', 'June%2018');
SELECT project_id,
'FP' as Phase,
OriginalCommitments,
ApprovedCommitmentChanges,
OriginalCommitments+ApprovedCommitmentChanges as CurrentAssigned,
sum(ProjectCostBudget.PendingChangeOrders) as PendingScopeChanges
sum(ProjectCost.CurrentWorkCompleted) +
sum(ProjectCost.EstimateToComplete) as EAC,
(sum(ProjectCost.CurrentWorkCompleted) +
sum(ProjectCost.EstimateToComplete) /
(sum(ProjectCostBudget.OriginalContractPrice +
ProjectCostBudget.RegisteredChangeOrders))) as PercentComplete
FROM `RCLY-DEV`.project
join ImportCost on ImportCost.ProjectID = project.pmis
join ProjectCostBudget on ProjectCostBudget.ProjectID = project.project_id
join ProjectCost on ProjectCost.ProjectID = project.project_id
join query_params_tmp qp on
qp.ProjectID = ImportCost.ProjectID and
qp.ImpCostTask = ImportCost.Task and
qp.PCBID = ProjectCostBudget.ProjectID and
ProjectCost.MonthYear like qp.MonthYear
GROUP BY OriginalCommitments, ApprovedCommitmentChanges;
END
【讨论】:
我喜欢这个思考过程,但是当我运行它时它返回 0 条记录。 临时表填充中有错字。你可以再试一次。如果没有返回想要的结果,请以 SQLFiddle 的形式提供示例数据。 我实际上是在跑步之前抓住了这一点。我会尝试在 SQL Fiddle 中加入一些东西【参考方案2】:如果我正确理解了你的问题,那么下面将解决。
使用标识列创建临时表,然后将数据插入其中。如果临时表没有唯一列,这将有助于遍历每条记录
--declare variable
DECLARE @ID INT,
@Task VARCHAR(256),
@ProjectID INT,
...
...
...
SELECT @ID = MIN(ID)
FROM TemporaryTable
WHILE ISNULL(@ID, '') <> ''
BEGIN
SELECT @Task = ImpCostTask
,@ProjectID = PCBID
...
...
...
FROM TemporaryTable
WHERE ID = @ID
insert into TempTable(
SELECT project_id,
'FP' as Phase,
OriginalCommitments,
ApprovedCommitmentChanges,
....
....
....
....
FROM `RCLY-DEV`.project
inner join ImportCost on ImportCost.ProjectID = project.pmis
inner join ProjectCostBudget on ProjectCostBudget.ProjectID = project.project_id
inner join ProjectCost on ProjectCost.ProjectID = project.project_id
where ImportCost.ProjectID = @ProjectID
and ImportCost.Task = @Task
and ProjectCostBudget.ProjectID = @ProjectID
....
....
....
....
....
....
....
);
SELECT @ID = MIN(ID)
FROM TemporaryTable
WHERE ID > @ID
END
【讨论】:
语法适用于 MSSQL,而问题适用于 mysql以上是关于MySQL存储过程循环遍历变量并插入临时表的主要内容,如果未能解决你的问题,请参考以下文章