【问题标题】:Create multiple temp tables in stored procedure using Prepared queries not working使用准备好的查询在存储过程中创建多个临时表不起作用
【发布时间】:2020-04-10 00:12:35
【问题描述】:

设置

  • MySQL 5.7 或 5.6

在下面的存储过程中,我要做的是创建一些临时表。其中一些是简单和静态的,其中 2 个是动态的(TempQuery1、TempQuery2)。

所有临时表都是先构建->准备->执行的。然后执行使用临时表 (GetQuery) 的主查询。

问题

当完全像在新连接上执行时,我得到 ​​p>

 Error Code: 1146. Table 'Job1111.TempPipeER' doesn't exist

这让我认为我有打字机或其他东西。在测试中,我发现如果我按照接下来的几个步骤进行操作,效果很好。

  • 注释掉 Query2 和 GetQuery 的 Prepare and Execute
  • 保存存储过程并运行 2 次。 (从 Deallocate 得到预期错误)
  • 取消注释查询 2。
  • 保存存储过程并再运行 2 次。 (从 Deallocate 得到预期错误)
  • 最后取消所有 Prepares 和 Executes 的注释
  • 保存并运行存储过程...现在可以使用了。

问题

  • 为什么我必须通过这些步骤才能让它一次构建一个临时表。
  • 后续执行是否要等上一个执行完成后再开始?
  • 有没有办法强制过程等待执行/表构建完成?
  • 有没有一种方法可以使用 signal/echo/console.log() 类型的方法来准确显示临时表构建的完成和执行的开始,以证明这甚至是我的真正问题?

观察/猜测

它的行为方式就像 Execute BuildGetQuery 在 TempTable Job1111.TempPipeER 完成构建之前执行。而 sine GetQuery 在 Join 中使用了 TempPipeER。 GetQuery 失败。

但是,如果我一次慢慢地构建每个表,那么它在 MySQL 工作台会话期间可以正常工作。

存储过程创建语句

DROP PROCEDURE IF EXISTS `Job1111`.`GetPipeStats`;
DELIMITER $$
CREATE DEFINER=`PSAAdmin`@`%` PROCEDURE `Job1111`.`GetPipeStats`( IN GroupedBy varchar(24))
BEGIN

### Declare Variables ###
DECLARE MechHoursPercent DECIMAL(3,2);
DECLARE TestingHoursPercent DECIMAL(3,2);
DECLARE CompleteForTestPercent DECIMAL(3,2);
DECLARE HydroHoursPercent DECIMAL(3,2);
DECLARE ClientTurnoverPercent DECIMAL(3,2);

### Set Variables ###
SELECT Value1 INTO MechHoursPercent
FROM `Job1111`.SETTINGS WHERE Label = "MechHoursPercent";
SELECT Value1 INTO TestingHoursPercent
FROM `Job1111`.SETTINGS WHERE Label = "TestingHoursPercent";
SELECT Value1 INTO CompleteForTestPercent
FROM `Job1111`.SETTINGS WHERE Label = "CompleteForTestPercent";
SELECT Value1 INTO HydroHoursPercent
FROM `Job1111`.SETTINGS WHERE Label = "HydroHoursPercent";
SELECT Value1 INTO ClientTurnoverPercent
FROM `Job1111`.SETTINGS WHERE Label = "ClientTurnoverPercent";





### Build Temp Table Queries ###
#DROP TABLE IF EXISTS `Job1111`.`TempPipeER`, `Job1111`.`TempPipeERT`;

SET @TempQuery1 = CONCAT('
CREATE TEMPORARY TABLE `Job1111`.`TempPipeER`(
INDEX `TempPipeER1` (`ID` ASC)
)
SELECT ID, BidID,  
sum(EarnedErectionHours) AS EarnedErectionHours, 
sum(EarnedBoltUpHours) AS EarnedBoltUpHours, 
sum(EarnedWeldHours) AS EarnedWeldHours, 
sum(EarnedCutHours) AS EarnedCutHours, 
sum(EarnedTrimHours) AS EarnedTrimHours, 
sum(EarnedSupportHours) AS EarnedSupportHours, 
sum(EarnedDemoHours) AS EarnedDemoHours, 
sum(EarnedMiscHours) AS EarnedMiscHours, 
sum(InstalledFootage) AS InstalledFootage, 
sum(InstalledBoltUps) AS InstalledBoltUps, 
sum(InstalledWelds) AS InstalledWelds, 
sum(InstalledCuts) AS InstalledCuts, 
sum(InstalledTrim) AS InstalledTrim, 
sum(InstalledSupports) AS InstalledSupports, 
sum(InstalledMisc) AS InstalledMisc, 
sum(InstalledDemo) AS  InstalledDemo

                FROM(SELECT min(td.ID) AS ID,td.BidID,

IF( 
COALESCE(se.ErectionLengthSpool1,0) 
+ COALESCE(se.ErectionLengthSpool2,0) 
+ COALESCE(se.ErectionLengthSpool3,0) 
+ COALESCE(se.ErectionLengthSpool4,0) 
+ COALESCE(se.ErectionLengthSpool5,0) 
+ COALESCE(se.ErectionLengthSpool6,0)
+ COALESCE(sme.MiscQuantity,0)
+ sum(COALESCE(cse.InstalledQuantity,0)) > td.TakeOffQuantity, /*Is Installed Greater then TakeOff*/
/*TRUE*/ GREATEST(td.TakeOffQuantity - sum(COALESCE(cse.InstalledQuantity,0)),0) * (td.EstimatedHours * ' ,MechHoursPercent, ' / td.TakeOffQuantity),
/*FALSE*/
COALESCE((td.EstimatedHours*' ,MechHoursPercent, '/td.TakeOffQuantity) 
* (COALESCE(se.ErectionLengthSpool1,0) 
+ COALESCE(se.ErectionLengthSpool2,0) 
+ COALESCE(se.ErectionLengthSpool3,0) 
+ COALESCE(se.ErectionLengthSpool4,0) 
+ COALESCE(se.ErectionLengthSpool5,0) 
+ COALESCE(se.ErectionLengthSpool6,0) 
+ COALESCE(sme.MiscQuantity,0)),0)
) AS EarnedErectionHours,

IF(COALESCE(sb.BoltUpQuantity,0) + COALESCE(smb.MiscQuantity,0) + sum(COALESCE(csb.InstalledQuantity,0))
    > td.TakeOffQuantity,/*Is Installed Greater then TakeOff*/
    /*TRUE*/ GREATEST(td.TakeOffQuantity - sum(COALESCE(csb.InstalledQuantity,0)),0) * (td.EstimatedHours * ' ,MechHoursPercent, ' / td.TakeOffQuantity),
    /*FALSE*/ COALESCE((td.EstimatedHours*' ,MechHoursPercent, '/td.TakeOffQuantity) * (COALESCE(sb.BoltUpQuantity,0)+COALESCE(smb.MiscQuantity,0)), 0)
    ) AS EarnedBoltUpHours,

IF(COALESCE(sw.WeldPercentCompleted * .01,0) + COALESCE(smw.MiscQuantity,0) + sum(COALESCE(csw.InstalledQuantity * .01,0))
    > td.TakeOffQuantity,/*Is Installed Greater then TakeOff*/
    /*TRUE*/ GREATEST(td.TakeOffQuantity - sum(COALESCE(csw.InstalledQuantity,0)),0) * (td.EstimatedHours * ' ,MechHoursPercent, ' / td.TakeOffQuantity),
    /*FALSE*/ COALESCE((td.EstimatedHours*' ,MechHoursPercent, '/td.TakeOffQuantity) * (COALESCE(sw.WeldPercentCompleted * .01,0)+COALESCE(smw.MiscQuantity,0)),0)
    ) AS EarnedWeldHours,

IF(COALESCE(scut.WeldPercentCompleted * .01,0) + COALESCE(smc.MiscQuantity,0) + sum(COALESCE(csc.InstalledQuantity * .01,0))
    > td.TakeOffQuantity,/*Is Installed Greater then TakeOff*/
    /*TRUE*/ GREATEST(td.TakeOffQuantity - sum(COALESCE(csc.InstalledQuantity,0)),0) * (td.EstimatedHours * ' ,MechHoursPercent, ' / td.TakeOffQuantity),
    /*FALSE*/ COALESCE((td.EstimatedHours*' ,MechHoursPercent, '/td.TakeOffQuantity) * (COALESCE(scut.WeldPercentCompleted * .01,0)+COALESCE(smc.MiscQuantity,0)),0)
    ) AS EarnedCutHours,

IF(COALESCE(st.TrimQuantity,0) + COALESCE(smt.MiscQuantity,0) + sum(COALESCE(cst.InstalledQuantity,0))
    > td.TakeOffQuantity,/*Is Installed Greater then TakeOff*/
    /*TRUE*/ GREATEST(td.TakeOffQuantity - sum(COALESCE(cst.InstalledQuantity,0)),0) * (td.EstimatedHours * ' ,MechHoursPercent, ' / td.TakeOffQuantity),
    /*FALSE*/ COALESCE((td.EstimatedHours*' ,MechHoursPercent, '/td.TakeOffQuantity) * (COALESCE(st.TrimQuantity,0)+COALESCE(smt.MiscQuantity,0)),0)
    ) AS EarnedTrimHours,

IF(COALESCE(ssu.SupportInstalled,0) + COALESCE(smssu.MiscQuantity,0) + sum(COALESCE(cssu.InstalledQuantity,0))
    > td.TakeOffQuantity,/*Is Installed Greater then TakeOff*/
    /*TRUE*/ GREATEST(td.TakeOffQuantity - sum(COALESCE(cssu.InstalledQuantity,0)),0) * (td.EstimatedHours * ' ,MechHoursPercent, ' / td.TakeOffQuantity),
    /*FALSE*/ COALESCE((td.EstimatedHours*' ,MechHoursPercent, '/td.TakeOffQuantity)*(COALESCE(ssu.SupportInstalled,0)+COALESCE(smssu.MiscQuantity,0)),0)
    ) AS EarnedSupportHours,

IF(COALESCE(sde.DemoQuantity,0) + COALESCE(smd.MiscQuantity,0) + sum(COALESCE(csd.InstalledQuantity,0))
    > td.TakeOffQuantity,/*Is Installed Greater then TakeOff*/
    /*TRUE*/ GREATEST(td.TakeOffQuantity - sum(COALESCE(csd.InstalledQuantity,0)),0) * (td.EstimatedHours * ' ,MechHoursPercent, ' / td.TakeOffQuantity),
    /*FALSE*/ COALESCE((td.EstimatedHours/td.TakeOffQuantity) * (COALESCE(sde.DemoQuantity,0)+COALESCE(smd.MiscQuantity,0)),0)
    ) AS EarnedDemoHours,

IF(COALESCE(sm.MiscQuantity,0) + sum(COALESCE(csm.InstalledQuantity,0))
    > td.TakeOffQuantity,/*Is Installed Greater then TakeOff*/
    /*TRUE*/ GREATEST(td.TakeOffQuantity - sum(COALESCE(csm.InstalledQuantity,0)),0) * (td.EstimatedHours * ' ,MechHoursPercent, ' / td.TakeOffQuantity),
    /*FALSE*/ COALESCE((td.EstimatedHours*' ,MechHoursPercent, '/td.TakeOffQuantity) * COALESCE(sm.MiscQuantity,0),0)
    ) AS EarnedMiscHours,


sum(COALESCE(se.ErectionLengthSpool1,0) + COALESCE(se.ErectionLengthSpool2,0) + COALESCE(se.ErectionLengthSpool3,0) + COALESCE(se.ErectionLengthSpool4,0) + COALESCE(se.ErectionLengthSpool5,0) + COALESCE(se.ErectionLengthSpool6,0) + COALESCE(sme.MiscQuantity,0)) AS InstalledFootage,
sum(COALESCE(sb.BoltUpQuantity,0) + COALESCE(smb.MiscQuantity,0)) AS InstalledBoltUps, 
sum(COALESCE(sw.WeldPercentCompleted * .01,0) + COALESCE(smw.MiscQuantity,0)) AS InstalledWelds,
sum(COALESCE(scut.WeldPercentCompleted * .01,0) + COALESCE(smc.MiscQuantity,0)) AS InstalledCuts,
sum(COALESCE(st.TrimQuantity,0) + COALESCE(smt.MiscQuantity,0)) AS InstalledTrim,
sum(COALESCE(ssu.SupportInstalled,0) + COALESCE(smssu.MiscQuantity,0)) AS InstalledSupports,
sum(COALESCE(sm.MiscQuantity,0)) AS InstalledMisc,
sum(COALESCE(sde.DemoQuantity,0) + COALESCE(smd.MiscQuantity,0)) AS InstalledDemo


FROM `Job1111`.SubmissionStatus ss
    JOIN PSA.REF_ActivityTypes at
        ON at.ID = ss.ActivityType

    LEFT JOIN `Job1111`.SubsErection se
        ON se.ID = ss.ActivityRowId AND ss.ActivityType = 11 AND se.ErectionRework = 0

    LEFT JOIN `Job1111`.SubsBoltUp sb
        ON sb.ID = ss.ActivityRowId AND ss.ActivityType = 21 AND sb.BoltUpRework = 0

    LEFT JOIN `Job1111`.SubsWeld sw
        ON sw.ID = ss.ActivityRowId AND ss.ActivityType = 22 AND  sw.WeldRework = 0

    LEFT JOIN `Job1111`.SubsWeld scut
        ON scut.ID = ss.ActivityRowId AND ss.ActivityType = 23 AND scut.WeldRework = 0

    LEFT JOIN `Job1111`.SubsTrim st
        ON st.ID = ss.ActivityRowId AND ss.ActivityType IN (30,31,33,34,35,39) AND st.TrimRework = 0

    LEFT JOIN (SELECT ssu.ID, COALESCE((ssu.SupportPercentCompleted * .01 * ssu.SupportQuantity),0) AS SupportInstalled
                FROM `Job1111`.SubsSupports ssu
                WHERE ssu.SupportRework = 0) ssu
        ON ssu.ID = ss.ActivityRowId AND ss.ActivityType = 32     

    LEFT JOIN `Job1111`.SubsDemo sde
        ON sde.ID = ss.ActivityRowId AND ss.ActivityType IN (50,51,52,53,59)

    LEFT JOIN `Job1111`.`TempTrackerDetailsPipe`td
        ON td.BidID = ss.fk_BidIDAssigned

/* #### Begining of Misc activities assigned joins #### */  
    LEFT JOIN `Job1111`.SubsMisc sm
        ON sm.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.ECT != "D" AND td.PipingActivityType = "MISC"  AND sm.MiscRework = 0

    LEFT JOIN `Job1111`.SubsMisc sme
        ON sme.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.PipingActivityType = "PE" AND sme.MiscRework = 0

    LEFT JOIN `Job1111`.SubsMisc smb
        ON smb.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.PipingActivityType = "BU" AND smb.MiscRework = 0

    LEFT JOIN `Job1111`.SubsMisc smw
        ON smw.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.PipingActivityType = "W" AND smw.MiscRework = 0

    LEFT JOIN `Job1111`.SubsMisc smc
        ON smc.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.ECT != "D" AND td.PipingActivityType = "CUT" AND smc.MiscRework = 0

    LEFT JOIN `Job1111`.SubsMisc smt
        ON smt.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.ECT = "T" AND td.PipingActivityType IN ("V","Plug","HpLp","Other","Blind") AND smt.MiscRework = 0

    LEFT JOIN `Job1111`.SubsMisc smssu
        ON smssu.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.PipingActivityType = "S" AND smssu.MiscRework = 0

    LEFT JOIN `Job1111`.SubsMisc smd
        ON smd.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.ECT = "D" AND smd.MiscRework = 0


/* #### Begining of Cumulative Past sums Calculation #### */    
    LEFT JOIN `Job1111`.`TempPipeCSE` cse
        ON ss.ActivityType IN (11,91) AND ss.fk_BidIDAssigned = cse.fk_BidIDAssigned AND cse.PSAActivityID < ss.PSAActivityID

    LEFT JOIN `Job1111`.`TempPipeCSB` csb
        ON ss.ActivityType IN (21,91) AND ss.fk_BidIDAssigned = csb.fk_BidIDAssigned AND csb.PSAActivityID < ss.PSAActivityID

    LEFT JOIN `Job1111`.`TempPipeCSW` csw
        ON ss.ActivityType IN (22,91) AND ss.fk_BidIDAssigned = csw.fk_BidIDAssigned AND csw.PSAActivityID < ss.PSAActivityID

    LEFT JOIN `Job1111`.`TempPipeCSC` csc
        ON ss.ActivityType IN (23,91) AND ss.fk_BidIDAssigned = csc.fk_BidIDAssigned AND csc.PSAActivityID < ss.PSAActivityID

    LEFT JOIN `Job1111`.`TempPipeCST` cst
        ON ss.ActivityType IN (30,31,33,34,35,39,91) AND ss.fk_BidIDAssigned = cst.fk_BidIDAssigned AND cst.PSAActivityID < ss.PSAActivityID

    LEFT JOIN `Job1111`.`TempPipeCSSU` cssu
        ON ss.ActivityType IN (32,91) AND ss.fk_BidIDAssigned = cssu.fk_BidIDAssigned AND cssu.PSAActivityID < ss.PSAActivityID

    LEFT JOIN `Job1111`.`TempPipeCSD` csd
        ON ss.ActivityType IN (50,51,52,53,59,91) AND ss.fk_BidIDAssigned = csd.fk_BidIDAssigned AND csd.PSAActivityID < ss.PSAActivityID

    LEFT JOIN `Job1111`.`TempPipeCSM` csm
        ON ss.ActivityType = 91 AND ss.fk_BidIDAssigned = csm.fk_BidIDAssigned AND csm.PSAActivityID < ss.PSAActivityID


WHERE fk_ActivityStatus IN (5,12)
AND ss.ActivityType IN (10,11,20,21,22,23,30,31,32,33,34,35,39,50,51,52,53,59,90,91,93)
GROUP BY ss.PSAActivityID)er0
GROUP BY BidID
');

SET @TempQuery2 = CONCAT('
CREATE TEMPORARY TABLE `Job1111`.`TempPipeERT`(
INDEX `TempPipeERT1` (`ID` ASC)
)
SELECT min(td.ID) AS ID, td.BidID,

IF(
    (COALESCE(td.EstimatedHours,0)*' ,TestingHoursPercent, '*' ,CompleteForTestPercent, ' * sum(COALESCE(steR.InstalledReadyForTesting, 0)))
    > COALESCE(td.EstimatedHours,0)*' ,TestingHoursPercent, '*' ,CompleteForTestPercent, ',
    /*TRUE*/
    COALESCE(td.EstimatedHours,0)*' ,TestingHoursPercent, '*' ,CompleteForTestPercent, ',
    /*FALSE*/
    (COALESCE(td.EstimatedHours,0)*' ,TestingHoursPercent, '*' ,CompleteForTestPercent, ' * sum(COALESCE(steR.InstalledReadyForTesting, 0)))
) AS EarnedReadyForTestingHours,

IF(
    (COALESCE(td.EstimatedHours,0)*' ,TestingHoursPercent, '*' ,HydroHoursPercent, ' * sum(COALESCE(steH.InstalledHydro, 0)))
    > COALESCE(td.EstimatedHours,0)*' ,TestingHoursPercent, '*' ,HydroHoursPercent, ',
    /*TRUE*/
    COALESCE(td.EstimatedHours,0)*' ,TestingHoursPercent, '*' ,HydroHoursPercent, ',
    /*FALSE*/
    (COALESCE(td.EstimatedHours,0)*' ,TestingHoursPercent, '*' ,HydroHoursPercent, ' * sum(COALESCE(steH.InstalledHydro, 0)))
) AS EarnedHydroHours,

IF(
    (COALESCE(td.EstimatedHours,0)*' ,TestingHoursPercent, '*' ,ClientTurnoverPercent, ' * sum(COALESCE(steC.InstalledClientTurnover, 0))) 
    > COALESCE(td.EstimatedHours,0)*' ,TestingHoursPercent, '*' ,ClientTurnoverPercent, ',
    /*TRUE*/
    COALESCE(td.EstimatedHours,0)*' ,TestingHoursPercent, '*' ,ClientTurnoverPercent, ',
    /*FALSE*/
    (COALESCE(td.EstimatedHours,0)*' ,TestingHoursPercent, '*' ,ClientTurnoverPercent, ' * sum(COALESCE(steC.InstalledClientTurnover, 0))) 
) AS EarnedClientTurnoverHours

FROM `Job1111`.trackerDetails td

LEFT JOIN (SELECT ste.ActivityType, ste.TestingTestPackageNumber, 1 AS InstalledReadyForTesting
            FROM `Job1111`.SubsTesting ste
            JOIN `Job1111`.SubmissionStatus ss
                ON ss.ActivityRowId = ste.ID AND ss.ActivityType = 41 AND ss.fk_ActivityStatus IN (5,12) AND ste.TestingRework = 0) steR
    ON steR.TestingTestPackageNumber = td.TestPackageNumber AND steR.ActivityType = 41 AND td.ECT != "D"

LEFT JOIN (SELECT ste.ActivityType, ste.TestingTestPackageNumber, 1 AS InstalledHydro
            FROM `Job1111`.SubsTesting ste
            JOIN `Job1111`.SubmissionStatus ss
                ON ss.ActivityRowId = ste.ID AND ss.ActivityType = 42 AND ss.fk_ActivityStatus IN (5,12) AND ste.TestingRework = 0) steH
    ON steH.TestingTestPackageNumber = td.TestPackageNumber AND steH.ActivityType = 42 AND td.ECT != "D"

LEFT JOIN (SELECT ste.ActivityType, ste.TestingTestPackageNumber, 1 AS InstalledClientTurnover
            FROM `Job1111`.SubsTesting ste
            JOIN `Job1111`.SubmissionStatus ss
                ON ss.ActivityRowId = ste.ID AND ss.ActivityType = 43 AND ss.fk_ActivityStatus IN (5,12) AND ste.TestingRework = 0) steC
    ON steC.TestingTestPackageNumber = td.TestPackageNumber AND steC.ActivityType = 43 AND td.ECT != "D"

GROUP BY td.BidID
');

### Build Main Query ###
SET @GetQuery = CONCAT('
QUERY REMOVED DUE TO BODY SIZE LIMIT
');



### Execute NON Prep Queries ###
DROP TABLE IF EXISTS `Job1111`.`TempTrackerDetailsPipe`;
CREATE TEMPORARY TABLE `Job1111`.`TempTrackerDetailsPipe`(
INDEX `TempPipeTD1` (`BidID` ASC),
INDEX `TempPipeTD2` (`PipingActivityType` ASC, `ECT` ASC),
INDEX `TempPipeTD3` (`ECT` ASC)
)
SELECT min(ID) AS ID, BidID, sum(TakeOffQuantity) AS TakeOffQuantity, sum(EstimatedHours) AS EstimatedHours, ECT, PipingActivityType
FROM`Job1111`.`trackerDetails`
GROUP BY BidID;


DROP TABLE IF EXISTS `Job1111`.`TempPipeCSE`;
CREATE TEMPORARY TABLE `Job1111`.`TempPipeCSE`(
INDEX `TempPipeCSE1` (`fk_BidIDAssigned` ASC, `PSAActivityID` ASC)
)
SELECT ss.PSAActivityID, ss.fk_BidIDAssigned, (COALESCE(ErectionLengthSpool1,0) + COALESCE(ErectionLengthSpool2,0) + COALESCE(ErectionLengthSpool3,0) + COALESCE(ErectionLengthSpool4,0) + COALESCE(ErectionLengthSpool5,0) + COALESCE(ErectionLengthSpool6,0) + COALESCE(sme.MiscQuantity,0)) AS InstalledQuantity
FROM `Job1111`.SubmissionStatus ss
LEFT JOIN `Job1111`.SubsErection 
    ON ss.ActivityType = 11 AND ss.ActivityRowId = ID AND ErectionRework = 0
LEFT JOIN `Job1111`.`TempTrackerDetailsPipe` td
    ON td.BidID = ss.fk_BidIDAssigned 
LEFT JOIN `Job1111`.SubsMisc sme
    ON sme.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.PipingActivityType = "PE" AND sme.MiscRework = 0
WHERE ss.fk_ActivityStatus IN (5,12)
AND ss.ActivityType IN (11,91)
HAVING InstalledQuantity > 0;


DROP TABLE IF EXISTS `Job1111`.`TempPipeCSB`;
CREATE TEMPORARY TABLE `Job1111`.`TempPipeCSB`(
INDEX `TempPipeCSB1` (`fk_BidIDAssigned` ASC, `PSAActivityID` ASC)
)
SELECT ss.PSAActivityID, ss.fk_BidIDAssigned, (COALESCE(BoltUpQuantity,0) + COALESCE(smb.MiscQuantity,0)) AS InstalledQuantity
FROM `Job1111`.SubmissionStatus ss
LEFT JOIN `Job1111`.SubsBoltUp 
    ON ss.ActivityType = 21 AND ss.ActivityRowId = ID AND BoltUpRework = 0
LEFT JOIN `Job1111`.`TempTrackerDetailsPipe` td
    ON td.BidID = ss.fk_BidIDAssigned           
LEFT JOIN `Job1111`.SubsMisc smb
    ON smb.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.PipingActivityType = "BU" AND smb.MiscRework = 0
WHERE ss.fk_ActivityStatus IN (5,12)
AND ss.ActivityType IN (21,91)
HAVING InstalledQuantity > 0;


DROP TABLE IF EXISTS `Job1111`.`TempPipeCSW`;
CREATE TEMPORARY TABLE `Job1111`.`TempPipeCSW`(
INDEX `TempPipeCSW1` (`fk_BidIDAssigned` ASC, `PSAActivityID` ASC)
)
SELECT ss.PSAActivityID, ss.fk_BidIDAssigned, (COALESCE(WeldPercentCompleted,0) + COALESCE(smw.MiscQuantity,0)) AS InstalledQuantity
FROM `Job1111`.SubmissionStatus ss
LEFT JOIN `Job1111`.SubsWeld
    ON ss.ActivityType = 22 AND ss.ActivityRowId = ID AND WeldRework = 0
LEFT JOIN `Job1111`.`TempTrackerDetailsPipe`td
    ON td.BidID = ss.fk_BidIDAssigned 
LEFT JOIN `Job1111`.SubsMisc smw
    ON smw.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.PipingActivityType = "W"AND smw.MiscRework = 0
WHERE ss.fk_ActivityStatus IN (5,12)
AND ss.ActivityType IN (22,91)
HAVING InstalledQuantity > 0;


DROP TABLE IF EXISTS `Job1111`.`TempPipeCSC`;
CREATE TEMPORARY TABLE `Job1111`.`TempPipeCSC`(
INDEX `TempPipeCSC1` (`fk_BidIDAssigned` ASC, `PSAActivityID` ASC)
)
SELECT ss.PSAActivityID, ss.fk_BidIDAssigned, (COALESCE(WeldPercentCompleted,0) + COALESCE(smc.MiscQuantity,0)) AS InstalledQuantity
FROM `Job1111`.SubmissionStatus ss
LEFT JOIN `Job1111`.SubsWeld
    ON ss.ActivityType = 23 AND ss.ActivityRowId = ID AND WeldRework = 0
LEFT JOIN `Job1111`.`TempTrackerDetailsPipe`td
    ON td.BidID = ss.fk_BidIDAssigned 
LEFT JOIN `Job1111`.SubsMisc smc
    ON smc.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.ECT != "D" AND td.PipingActivityType = "CUT" AND smc.MiscRework = 0
WHERE ss.fk_ActivityStatus IN (5,12)
AND ss.ActivityType IN (23,91)
HAVING InstalledQuantity > 0;


DROP TABLE IF EXISTS `Job1111`.`TempPipeCST`;
CREATE TEMPORARY TABLE `Job1111`.`TempPipeCST`(
INDEX `TempPipeCST1` (`fk_BidIDAssigned` ASC, `PSAActivityID` ASC)
)
SELECT ss.PSAActivityID, ss.fk_BidIDAssigned, (COALESCE(TrimQuantity,0) + COALESCE(smt.MiscQuantity,0)) AS InstalledQuantity
FROM `Job1111`.SubmissionStatus ss
LEFT JOIN `Job1111`.SubsTrim
    ON ss.ActivityType IN (30,31,33,34,35,39) AND ss.ActivityRowId = ID AND TrimRework = 0
LEFT JOIN `Job1111`.`TempTrackerDetailsPipe` td
    ON td.BidID = ss.fk_BidIDAssigned
LEFT JOIN `Job1111`.SubsMisc smt
    ON smt.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.ECT = "T" AND td.PipingActivityType IN ("V","Plug","HpLp","Other","Blind")AND smt.MiscRework = 0
WHERE ss.fk_ActivityStatus IN (5,12)
AND ss.ActivityType IN (30,31,33,34,35,39,91)
HAVING InstalledQuantity > 0;


DROP TABLE IF EXISTS `Job1111`.`TempPipeCSSU`;
CREATE TEMPORARY TABLE `Job1111`.`TempPipeCSSU`(
INDEX `TempPipeCSSU1` (`fk_BidIDAssigned` ASC, `PSAActivityID` ASC)
)
SELECT ss.PSAActivityID, ss.fk_BidIDAssigned, (COALESCE(SupportQuantity,0) + COALESCE(smssu.MiscQuantity,0)) AS InstalledQuantity
FROM `Job1111`.SubmissionStatus ss
LEFT JOIN `Job1111`.SubsSupports
    ON ss.ActivityType = 32 AND ss.ActivityRowId = ID AND SupportRework = 0
LEFT JOIN `Job1111`.`TempTrackerDetailsPipe` td
    ON td.BidID = ss.fk_BidIDAssigned
LEFT JOIN `Job1111`.SubsMisc smssu
    ON smssu.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.PipingActivityType = "S" AND smssu.MiscRework = 0
WHERE ss.fk_ActivityStatus IN (5,12)
HAVING InstalledQuantity > 0;


DROP TABLE IF EXISTS `Job1111`.`TempPipeCSD`;
CREATE TEMPORARY TABLE `Job1111`.`TempPipeCSD`(
INDEX `TempPipeCSD` (`fk_BidIDAssigned` ASC, `PSAActivityID` ASC)
)
SELECT ss.PSAActivityID, ss.fk_BidIDAssigned, (COALESCE(DemoQuantity,0) + COALESCE(smd.MiscQuantity,0)) AS InstalledQuantity
FROM `Job1111`.SubmissionStatus ss
LEFT JOIN `Job1111`.SubsDemo
    ON ss.ActivityType IN (50,51,52,53,59) AND ss.ActivityRowId = ID
LEFT JOIN `Job1111`.`TempTrackerDetailsPipe` td
    ON td.BidID = ss.fk_BidIDAssigned
LEFT JOIN `Job1111`.SubsMisc smd
    ON smd.ID = ss.ActivityRowId AND ss.ActivityType = 91 AND td.ECT = "D" AND smd.MiscRework = 0
WHERE ss.fk_ActivityStatus IN (5,12)
AND ss.ActivityType IN (50,51,52,53,59,91)
HAVING InstalledQuantity > 0;


DROP TABLE IF EXISTS `Job1111`.`TempPipeCSM`;
CREATE TEMPORARY TABLE `Job1111`.`TempPipeCSM`(
INDEX `TempPipeCSM` (`fk_BidIDAssigned` ASC, `PSAActivityID` ASC)
)
SELECT ss.PSAActivityID, ss.fk_BidIDAssigned, MiscQuantity AS InstalledQuantity
FROM `Job1111`.SubmissionStatus ss
LEFT JOIN `Job1111`.`TempTrackerDetailsPipe` td
    ON td.BidID = ss.fk_BidIDAssigned 
JOIN `Job1111`.SubsMisc sm
    ON ss.ActivityType = 91 AND ss.ActivityRowId = sm.ID AND td.PipingActivityType = "MISC"  AND td.ECT != "D" AND sm.MiscRework = 0
WHERE ss.fk_ActivityStatus IN (5,12);


### Prepare Queries to execute ###
PREPARE BuildTempQuery1 FROM @TempQuery1;
PREPARE BuildTempQuery2 FROM @TempQuery2;
PREPARE BuildGetQuery FROM @GetQuery;

### Execute Prep Queries ###
EXECUTE BuildTempQuery1;
EXECUTE BuildTempQuery2;
EXECUTE BuildGetQuery;


### Deallocate Execute Querys and Tables###
DEALLOCATE PREPARE BuildTempQuery1;
DEALLOCATE PREPARE BuildTempQuery2;
DEALLOCATE PREPARE BuildGetQuery;


END$$
DELIMITER ;

【问题讨论】:

  • 我可以满怀信心地告诉您,在临时表准备好使用之前不会继续执行,因此这不是时间问题。如果您使用DROP ... IF EXISTS,MySQL 5.1 会抛出一个 warning(不是错误),但这应该早就修复了,即便如此,它也只是一个警告。也许问题是您通过使用DROP TABLE IF EXISTS ... 而不是预期的(更安全的)DROP TEMPORARY TABLE IF EXISTS ... 来触发与此相关的错误。这有什么区别吗?
  • 不相关,不清楚为什么要将值连接到准备好的语句中。似乎? 占位符和EXECUTE stmt USING @var1, @var2, @var3, ... 会更正确、更安全等。或者至少使用内置的QUOTE() 函数来正确转义值并正确处理空值。
  • @Michael 您对参数的“更安全”使用绝对正确,而不是盲目地将变量组合成字符串。这样做的主要原因是它是一种更简单的原型设计方法,然后正确地处理 20 多个问号......除了这个存储过程只接收来自其他存储过程的调用,其中包含硬编码的参数,并且两次转义了用户参数观点。是的,不是“正确”,但不像脱离上下文那样开放。正等着有人喊出来。 :)

标签: mysql stored-procedures session-variables


【解决方案1】:

我看到你的代码的方式是你想要这样的查询:

CREATE TEMPORARY TABLE `database`.`temp_table` AS
SELECT user_id, name, address
FROM user
WHERE user_id = 3829;
ALTER TABLE `database`.`temp_table` 
ADD INDEX `index_name` (`user_id` ASC);

使用style 存储在session variable 中,如下所示:

SET @session_variable = CONCAT('
    CREATE TEMPORARY TABLE `database`.`temp_table` AS
    SELECT user_id, name, address
    FROM user
    WHERE user_id = 3829;
    ALTER TABLE `database`.`temp_table` 
    ADD INDEX `index_name` (`user_id` ASC);
');

但是你想要的style的正确方法是:

SET @session_variable = CONCAT('CREATE TEMPORARY TABLE `database`.`temp_table` AS ');
SET @session_variable = CONCAT(@session_variable, 'SELECT user_id, name, address ');
SET @session_variable = CONCAT(@session_variable, 'FROM user ');
SET @session_variable = CONCAT(@session_variable, 'WHERE user_id = 3829; ');
SET @session_variable = CONCAT(@session_variable, 'ALTER TABLE `database`.`temp_table` ');
SET @session_variable = CONCAT(@session_variable, 'ADD INDEX `index_name` (`user_id` ASC);'); 

或者像这样:

SET @session_variable = CONCAT(
    'CREATE TEMPORARY TABLE `database`.`temp_table` AS ',
    'SELECT user_id, name, address ',
    'FROM user ',
    'WHERE user_id = 3829; ',
    'ALTER TABLE `database`.`temp_table` ',
    'ADD INDEX `index_name` (`user_id` ASC); '
);

我想建议您在这里阅读有关Prepared StatementMySQL 的信息:https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html

希望我能帮上忙,干杯。

【讨论】:

  • 恕我直言,你到底在说什么朋友?不,不,非常非常不!为什么我不想浪费所有的时间和精力通过连接附加到其自身的每一行来构建会话变量。我完全不确定您从哪里得到这个问题与“样式”有关的想法我的陈述布局完全只是为了人类可读性。只要字符串系统正确,prepare 就不会关心空格或回车。我感谢您的努力,但您的回答中有很多不和误解..
  • 我所说的是你assign@TempQuery1 @TempQuery2@GetQuery 的值的方式@ MySQL 的引擎不会读取这样的多行连接。就是这样
  • 这是不正确的.. 它确实阅读了它们。我以前用过很多次。就像上面提到的那样,如果不是同时运行所有这些准备好的语句实际上都可以工作。
  • 好吧,我建议您需要测试那些子查询是否真正返回了其父查询的正确结果集。我能理解编码和语法的区别
  • 再次感谢您的意见。但这也已经在上面进行了测试、描述和证明,这不是问题。
【解决方案2】:

存储过程非常完善。除了一项。由于一些准备好的语句使用由其他准备好的语句制作的临时表。需要注意以正确的顺序准备和执行语句。

改变这个

### Prepare Queries to execute ###
PREPARE BuildTempQuery1 FROM @TempQuery1;
PREPARE BuildTempQuery2 FROM @TempQuery2;
PREPARE BuildGetQuery FROM @GetQuery;

### Execute Prep Queries ###
EXECUTE BuildTempQuery1;
EXECUTE BuildTempQuery2;
EXECUTE BuildGetQuery;


### Deallocate Execute Querys and Tables###
DEALLOCATE PREPARE BuildTempQuery1;
DEALLOCATE PREPARE BuildTempQuery2;
DEALLOCATE PREPARE BuildGetQuery;

至此

### Prepare Pass 1 Queries to execute ###
PREPARE BuildTempQuery1 FROM @TempQuery1;
PREPARE BuildTempQuery2 FROM @TempQuery2;

### Execute Pass 1 Queries ###
EXECUTE BuildTempQuery1 ;
EXECUTE BuildTempQuery2 ;


### Prepare Pass 2 Queries to execute ###
PREPARE BuildGetQuery FROM @GetQuery;

### Execute Pass 2 Queries ###
EXECUTE BuildGetQuery;



### Deallocate Execute Querys and Tables###
DEALLOCATE PREPARE BuildTempQueryER;
DEALLOCATE PREPARE BuildTempQueryERT;
DEALLOCATE PREPARE BuildGetQuery;

说明

之所以需要这样做,是因为“BuildGetQuery”正在寻找“BuildTempQuery1”创建的临时表。它必须在 BuildGetQuery 准备之前存在。

错误的想法是“这些表存在吗?”在执行“BuildGetQuery”期间执行的检查,其中查找在 BuildTempQuery1 和 BuildTempQuery1 中创建的表发生在 EXECUTE 而不是 PREPARE。
原来这个检查发生在“BuildGetQuery”的准备阶段。这意味着需要首先执行 Temp 查询。

我缺少的一个平静是在 MySQL 文档中解释/证明这一现实的地方。

【讨论】:

    猜你喜欢
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多