merge语句临时表 - 如何将数据导入本地数组?

时间:2014-01-28 17:51:33

标签: php sql merge olap

我们正在进行调试,因为我们的退役前任有一个查询语句,在上传到数据库之前将拉取的数据放入一系列临时表中。它现在不工作(我们向TestPatterns表中添加了项目,并且运行tp7而不是tp21,因此数据可能不同)并且我们很难调试它。如果我们可以以某种方式打印或访问放在临时表中的数据,也许我们可以更好地调试它。关于如何更好地调试这个的想法,也许看到数据?我们可以打印我们的第一个select / where语句,但不打印执行qry时它提取的数据。另外还有我们所做的Source / Target sql合并。 我们知道在执行$ qry1d之前,一切似乎都有效。

我在线查看了如何查看此信息,并查看了sql profiler,但我担心这些语句太复杂而无法破译探查器输出。当我尝试使用http://youtu.be/mJ8Dyv4Uk6E进行分析时,对于一个简单的选择前1000行,它说:

 exec sp_executesql N'SELECT
clmns.name AS [Name]
FROM
sys.tables AS tbl
INNER JOIN sys.all_columns AS clmns ON clmns.object_id=tbl.object_id
WHERE
(CAST(clmns.is_sparse AS bit)=@_msparam_0)and((tbl.name=@_msparam_1 and SCHEMA_NAME(tbl.schema_id)=@_msparam_2))
ORDER BY
clmns.column_id ASC',N'@_msparam_0 nvarchar(4000),@_msparam_1 nvarchar(4000),@_msparam_2 nvarchar(4000)',@_msparam_0=N'0',@_msparam_1=N'Measurements',@_msparam_2=N'dbo'

失败了
  

MERGE语句尝试更多地更新或删除同一行   不止一次。当目标行匹配多个源时会发生这种情况   行。 MERGE语句不能更新/删除目标的同一行   表多次。优化ON子句以确保目标行   匹配最多一个源行,或使用GROUP BY子句进行分组   源行。

这是一些php sql合并语句:

$qry = 'SELECT "PrintSamples"."PrintSampleID", "PrintSamples"."TestPatternName", "PrintSamples"."PrintCopyID", 
"DigitalImages"."CaptureTime", "PrintSampleAnalyses"."psaTicket", "Measurements"."MeasurementID", "Measurements"."MeasurementUuid", 
SUBSTRING("OperatorLastName",1,1) AS "lastInitial", SUBSTRING("OperatorFirstName",1,1) AS "firstInitial",
"ParameterValues"."ParameterID", "ParameterName", "TargetName", "ParameterValues"."ParameterValue"
FROM "ParameterValues"
LEFT JOIN "Measurements" ON "ParameterValues"."MeasurementID"="Measurements"."MeasurementID" 
LEFT JOIN "PrintSampleAnalyses" ON "PrintSampleAnalyses"."psaID"="Measurements"."psaID"
LEFT JOIN "DigitalImages" ON "DigitalImages"."ImageID"="PrintSampleAnalyses"."ImageID" 
LEFT JOIN "PrintSamples" ON "DigitalImages"."PrintSampleID"="PrintSamples"."PrintSampleID"
LEFT JOIN "Sessions" ON "Sessions"."SessionID"="PrintSampleAnalyses"."SessionID" 
LEFT JOIN "Operators" ON "Operators"."OperatorID"="Sessions"."OperatorID"
LEFT JOIN "ParameterNames" ON "ParameterNames"."ParameterID"="ParameterValues"."ParameterID"
LEFT JOIN "Targets" ON "Targets"."TargetID"="Measurements"."TargetID"
WHERE ('; 

//----------------------------------------------------------------------------------------------------
// The two statements where added to make AvgGhostValAsSir77 and MaxNegGhostingValAsSir77 work.
// After much testing it was found that the query did not recognize these to ParameterNames in the 
// Postgres database. It was never discovered why when testing the ParameterName to be equal to
// AvgGhostValAsSir77 or MaxNegGhostingValAsSir77 the query fails but using the LIKE statement 
// corrected the problem. It is possible that the names contain a hidden character or space that
// caused the proble. More investigation will need to be done to find a better resolution to this 
// strange problem. On 8/1/13 - It was found that the two Parameters AvgGhostValAsSir77 and MaxNegGhostingValAsSir77
// have a trailing space to thier names in the Postgres database and that's why these two parameters
// were NOT working. It was decided instead of having IQAF people modify the database that the two
// statements using the LIKE will remain in place. The file was modified on this date 8/1/13.
//----------------------------------------------------------------------------------------------------
// only take values that actually get reported on the dashboard
// this list comes from the "MeasurementNames" table
foreach ($measurementIDs as $mid){
    if($mid[0] == "AvgGhostValAsSir77") $qry .= '(("ParameterName" LIKE ' . "'%AvgGhostValAsSir77%'" . ') AND ("TargetName"=' . "'" . $mid[1] . "')) OR "; 
    else if($mid[0] == "MaxNegGhostingValAsSir77") $qry .= '(("ParameterName" LIKE ' . "'%MaxNegGhostingValAsSir77%'" . ') AND ("TargetName"=' . "'" . $mid[1] . "')) OR "; 
    else $qry .= '(("ParameterName"=' . "'" . $mid[0] . "'" . ') AND ("TargetName"=' . "'" . $mid[1] . "')) OR ";
}    
$qry = substr ($qry, 0, -4);
$qry .= ") ";

if (isset($captureTime)){   // used for incremental updates
    $qry .= ' AND ("CaptureTime">' . "'" . $captureTime . "')";
}
// steve invalid reading code is -99999. 
$qry .= ' AND ("ParameterValues"."ParameterValue" != -99999) ORDER BY "PrintSampleID", "MeasurementID"';

$actionString = '$action';

$qryCreate = "CREATE TABLE #tmpMeasurementTable (TestGUID uniqueidentifier, 
            IQAFid uniqueidentifier, pqID int, MeasurementID int,
            EvaluationDate datetime, EvaluatorID int, 
            TestUnitID int, TestUnitCountID int,
            TestPatternID int, ColorID int,
            TargetID int, ParameterID int,
            ParameterValue real)
            CREATE TABLE #MergeOutput (ActionType nvarchar(10))";
//start putting data into measurement tables
$qry1a= "INSERT INTO #tmpMeasurementTable VALUES ";
//put 1a data in MeasurementData
$qry1b = "
    MERGE INTO MeasurementData AS Target
    USING #tmpMeasurementTable AS Source 
    ON Target.pqID=Source.pqID 
        AND Target.MeasurementID=Source.MeasurementID  
        AND Target.TargetID=Source.TargetID  
        AND Target.ParameterID=Source.ParameterID 
        AND Target.TestPatternID=Source.TestPatternID 
        AND Target.IQAFMeasurementID=Source.IQAFid  
    WHEN MATCHED THEN
        UPDATE SET Target.ParameterValue = Source.ParameterValue,
                Target.TestUnitID=Source.TestUnitID, 
                Target.TestUnitCountID=Source.TestUnitCountID,
                Target.EvaluationDate=Source.EvaluationDate,  
                Target.EvaluatorID=Source.EvaluatorID  
    WHEN NOT MATCHED BY Target THEN
        INSERT (TestGUID, IQAFMeasurementID, pqID, 
                MeasurementID, EvaluationDate, EvaluatorID, 
                TestUnitID, TestUnitCountID, TestPatternID, ColorID,
                TargetID, ParameterID, ParameterValue)
        VALUES (Source.TestGUID, Source.IQAFid, Source.pqID, 
                Source.MeasurementID, Source.EvaluationDate, Source.EvaluatorID, 
                Source.TestUnitID, Source.TestUnitCountID,
                Source.TestPatternID, Source.ColorID, 
                Source.TargetID, Source.ParameterID, Source.ParameterValue)
    OUTPUT 
        $actionString INTO #MergeOutput;
        DROP TABLE #tmpMeasurementTable";

$qryOutput = "SELECT ActionType, COUNT(ActionType)AS [count] FROM #MergeOutput GROUP BY ActionType";
$qryCleanup = "DROP TABLE #MergeOutput";

$qry1c = "IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#MergeOutput') AND xtype='U')
            DROP TABLE #MergeOutput
    CREATE TABLE #MergeOutput (ActionType nvarchar(10))
    SELECT TestIndex AS TestID, TestID AS TestNumber, MeasurementData.TestGUID, pqID, TestUnitID, TestUnitCountID, TestPatternID,
  ColorID, MeasurementData.MeasurementID, TargetID, ParameterID,
  CAST(ROUND(AVG(ParameterValue*Multiplier), 2)AS DECIMAL(18,2)) AS Value
  INTO #tmpTable
  FROM MeasurementData
  LEFT JOIN Measurements ON Measurements.MeasurementID=MeasurementData.MeasurementID 
  LEFT JOIN Tests ON Tests.TestGUID=MeasurementData.TestGUID AND Tests.PiggybackID IS NULL 
  WHERE MeasurementData.TestGUID='" . $TestGUID . "' AND pqID>=" . $startPQid . " AND pqID<=" .$endPQid;


if (isset($captureTime))    // used for incremental updates
{
    $qry1c .= " AND EvaluationDate>'" . makeDateTime($captureTime) . "'";
}

$qry1c .= " GROUP BY TestIndex, TestID, MeasurementData.TestGUID, pqID, TestUnitID, TestUnitCountID, TestPatternID,
  ColorID, MeasurementData.MeasurementID, TargetID, ParameterID
  ORDER BY ColorID, TestPatternID, TestUnitCountID, MeasurementData.MeasurementID, TargetID, ParameterID;
  SELECT @@ROWCOUNT AS rows INTO #DashboardRows;";

//put temporary table in dashboard table
$qry1d = ";
    MERGE INTO DashboardData AS Target
    USING #tmpTable AS Source
    ON Target.pqID=Source.pqID 
        AND Target.MeasurementID=Source.MeasurementID  
        AND Target.TargetID=Source.TargetID  
        AND Target.ParameterID=Source.ParameterID 
        AND Target.TestPatternID=Source.TestPatternID 
    WHEN MATCHED THEN
        UPDATE SET Target.ParameterValue=Source.Value,
                Target.TestUnitID=Source.TestUnitID, 
                Target.TestUnitCountID=Source.TestUnitCountID 
    WHEN NOT MATCHED BY Target THEN
        INSERT (TestGUID, pqID, 
                MeasurementID, 
                TestUnitID, TestUnitCountID, TestPatternID, ColorID,
                TargetID, ParameterID, ParameterValue,
                TestNumber, TestIndex)
        VALUES (Source.TestGUID, Source.pqID,
                Source.MeasurementID,
                Source.TestUnitID, Source.TestUnitCountID,
                Source.TestPatternID, Source.ColorID, 
                Source.TargetID, Source.ParameterID, Source.Value, 
                Source.TestNumber, Source.TestID)
     OUTPUT 
        $actionString INTO #MergeOutput;
    DROP TABLE #tmpTable";

查询执行如下:

 $result = $ms_conn->query($qry1c);     $recordCount = $ms_conn->fetchOne
 ("SELECT rows FROM #DashboardRows");   //dataLog ("OLAP database " .
 $recordCount . " records to process", true);   $result =
 $ms_conn->query($qry1d); dataLog ("end dashboard query");

1 个答案:

答案 0 :(得分:1)

要查看中间表,请从表名中删除第一个字符#。这将使表不是临时的,因为SQL Server的惯例是,如果表的名称以此字符开头,则表是临时的。您可能还想从代码中删除drop table语句。然后你可以像对待任何其他表一样调查这些中间表。

当然,为了能够重新运行代码,您必须手动删除表。