【发布时间】:2014-02-20 04:36:18
【问题描述】:
我们在调试过程中遇到了困难,因为我们退休的前任有一个查询语句,该语句在上传到数据库之前将提取的数据放入一系列临时表中。它现在不起作用(我们在 TestPatterns 表中添加了项目,并为 tp7 而不是 tp21 运行,因此数据可能会有所不同)并且我们在调试它时遇到了困难。如果我们能以某种方式打印或访问放在临时表中的数据,也许我们可以更好地调试它。关于如何更好地调试这个的任何想法,也许看到数据?我们可以打印我们的第一个 select/where 语句,但不能打印它在执行 qry 时提取的数据。另外还有我们所做的 Source/Target sql 合并。 在我们执行 $qry1d 之前,我们知道一切似乎都可以正常工作。
我在网上查找了如何查看此信息,并查看了 sql 分析器,但我担心这些语句太复杂而无法破译分析器的输出。当我尝试使用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");
【问题讨论】: