我有一个很长且非常重复的查询,我需要每5分钟运行一次报告,下面的一个选择语句中有一些摘录,我有26列与此类似将需要运行总共6个不同的行,每个行有7个不同的where语句,基于时间范围,作业和运算符,所以不是创建大量的T-SQL,而是每隔5分钟运行一次考虑创建一个存储过程,其参数传递给它为两位数的行号(在下面的例子中为'05'),where条件和列的标识符(在下面的例子'Job'中)。我遇到的问题是连接select语句中的列名,我尝试了许多方法,但没有一个方法有效。
示例(是的,我知道大量的十进制转换,我想对一切都是varchar大喊大叫,但是将数据从我们的mfg机器传输到Db的应用程序只会写为字符串或日期时间的时间戳,并且charindex是因为我看到数据被放到小数点后20位,在极少数情况下甚至更远)
,AVG(CAST(LEFT("E05UP", (CHARINDEX(',', E05UP, 5) + 6)) AS decimal(11,6)))*100 AS JobE05Up
,AVG(CAST(LEFT(E05QUAL, (CHARINDEX(',', E05QUAL, 5) + 6)) AS decimal(11,6)))*100 AS JobE05Qual
,CASE WHEN AVG(CAST(LEFT(E05UP, (CHARINDEX(',', E05UP, 5) + 6)) AS decimal(11,6)))>0 AND AVG(CAST(LEFT(E05SPD, (CHARINDEX(',', E05SPD, 5) + 6)) AS decimal(11,6)))>0 AND
AVG(CAST(LEFT(E05QUAL, (CHARINDEX(',', E05QUAL, 5) + 6)) AS decimal(11,6)))>0 THEN (AVG(CAST(LEFT(E05UP, (CHARINDEX(',', E05UP, 5) + 6)) AS decimal(11,6)))*
(AVG(CAST(LEFT(E05SPD, (CHARINDEX(',', E05Spd, 5) + 6)) AS decimal(11,6)))/@E05SpeedMAX)*AVG(CAST(LEFT(E05QUAL, (CHARINDEX(',', E05QUAL, 5) + 6)) AS decimal(11,6)))*100)
ELSE 0 END AS JobE05OEE
我想要做的就是:
SELECT AVG(E+@P1+SPD) AS @P2+Speed FROM Test.Dbo.Line+@P1 WHERE @P3
编辑:整个查询仅从最后一个Db写入中选择数据,在将所有强制转换为函数之后,此报告的此查询和每个其他查询之间唯一的变化是行#(L05)由于我们将使用多行,因此列名,where子句以及被求和或平均的数字。
DECLARE @L05CurWO as INT
DECLARE @L05CurCount AS INT
DECLARE @L05SpeedMAX AS INT
DECLARE @E05SpeedMAX AS INT
DECLARE @H05SpeedMAX AS INT
DECLARE @P05SpeedMAX AS INT
DECLARE @C05SpeedMAX AS INT
DECLARE @L05CurQual AS Decimal(11,6)
--Set Maximum Line Speeds Speeds
SET @L05SpeedMAX = 147
SET @E05SpeedMAX = 147
SET @H05SpeedMAX = 147
SET @P05SpeedMAX = 147
SET @C05SpeedMAX = 147
SET @L05CurWO = (SELECT TOP 1 L05WO FROM WB.dbo.Line05 WHERE L05WO IS NOT NULL ORDER BY L05Time DESC)
SET @L05CurCount = (SELECT SUM(dbo.TOD(E05Count)) FROM WB.dbo.Line05 WHERE L05WO = @L05CurWO)
SET @L05CurQual = (SELECT TOP 1 CASE WHEN dbo.TOD(L05Count)<1 THEN 0 ELSE CASE WHEN dbo.TOD(L05Blowoff)<1 THEN 1 ELSE (1-(dbo.TOD(L05Blowoff)/
dbo.TOD(L05Count))) END END FROM WB.dbo.Line05 WHERE L05WO = @L05CurWO ORDER BY L05Time DESC)
--Select Current Numbers
SELECT TOP 1 @L05CurWO AS CurrentL05WorkOrder
,L05TE AS CurrentL05TE
,L05TF AS CurrentL05TF
,@L05CurCount AS CurrentL05Count
,@L05JobScrap AS CurrentL05Scrap
,L05QUAN AS CurrentL05Quantity
,dbo.TOD(L05UP)*100 AS CurrentL05Uptime
,dbo.TOD(C05SPD) AS CurrentL05Speed
,@L05CurQual*100 AS CurrentL05Qual
,CASE WHEN dbo.ToD(L05UP)>0 AND dbo.ToD(C05SPD)>0 AND @L05CurQUAL>0 THEN dbo.ToD(L05UP)*(dbo.ToD(C05SPD)/@L05SpeedMAX)*@L05CurQual ELSE 0 END AS CurrentL05OEE
,dbo.ToD(E05SPD) AS CurrentE05Speed
,dbo.ToD(E05UP)*100 AS CurrentE05Up
,dbo.ToD(E05QUAL)*100 AS CurrentE05Qual
,CASE WHEN dbo.ToD(E05UP)>0 AND dbo.ToD(E05SPD)>0 AND dbo.ToD(E05QUAL)>0 THEN (dbo.ToD(E05UP)*(dbo.ToD(E05SPD)/@E05SpeedMAX)*(1-(dbo.ToD(E05Blowoff)/
dbo.ToD(E05Count)))*100) ELSE 0 END AS CurrentE05OEE
,dbo.ToD(H05SPD) AS CurrentH05Speed
,dbo.ToD(H05UP)*100 AS CurrentH05Up
,dbo.ToD(H05QUAL)*100 AS CurrentH05Qual
,CASE WHEN dbo.ToD(H05UP)>0 AND dbo.ToD(H05SPD)>0 AND dbo.ToD(H05QUAL)>0 THEN (dbo.ToD(H05UP)*(dbo.ToD(H05SPD)/@H05SpeedMAX)*(1-(dbo.ToD(H05Blowoff)/
dbo.ToD(H05Count)))*100) ELSE 0 END AS CurrentH05OEE
,dbo.ToD(P05SPD) AS CurrentP05Speed
,dbo.ToD(P05UP)*100 AS CurrentP05Up
,dbo.ToD(P05QUAL)*100 AS CurrentP05Qual
,CASE WHEN dbo.ToD(P05UP)>0 AND dbo.ToD(P05SPD)>0 AND dbo.ToD(P05QUAL)>0 THEN (dbo.ToD(P05UP)*(dbo.ToD(P05SPD)/@P05SpeedMAX)*(1-(dbo.ToD(P05Blowoff)/
dbo.ToD(P05Count)))*100) ELSE 0 END AS CurrentP05OEE
,dbo.ToD(C05SPD) AS CurrentC05Speed
,dbo.ToD(C05UP)*100 AS CurrentC05Up
,dbo.ToD(C05QUAL)*100 AS CurrentE05Qual
,CASE WHEN dbo.ToD(C05UP)>0 AND dbo.ToD(C05SPD)>0 AND dbo.ToD(C05QUAL)>0 THEN (dbo.ToD(C05UP)*(dbo.ToD(C05SPD)/@P05SpeedMAX)*(1-(dbo.ToD(C05Blowoff)/
dbo.ToD(C05Count)))*100) ELSE 0 END AS CurrentC05OEE
FROM WB.dbo.Line05
WHERE L05WO = @L05CurWO
ORDER BY L05Time DESC
答案 0 :(得分:2)
从
开始Create Function dbo.ToD(@val as varchar(max)) Returns Decimal(11, 6) As
Begin
Return Cast(Left(@val, (CharIndex(',', @val, 5) + 6)) As Decimal(11, 6))
End
我认为下一步是动态sql这样的事情会让你走上正轨。 (如果@Col来自用户输入,则会出现sql注入漏洞):
这是完全未经测试的,因此会出现愚蠢的错误。我也可能误解了从查询到查询的哪些位变化,哪些位保持不变。我不是100%确定通过动态sql设置参数的机制有效,但我在How to get sp_executesql result into a variable?读了它。您可能需要使用临时表。
Declare
@Col nvarchar(max) = '05',
@sql nvarchar(max),
@params nvarchar(max),
@CurWO int
-- Dynamically getting one of the current values
Set @sql = N'Set @CurWO = (' +
N'Select Top 1 L' + @Col + N'WO' +
N' From WB.dbo.Line' + @Col +
N' Where L' + @Col + N'WO Is Not Null' +
N' Order By L' + @Col + N'Time Desc)'
-- For diagnosing the inevitable errors
Print @sql
Set @params = N'@CurWO int output'
Exec sp_executesql @sql, @params, @CurWO Output
-- Dynamically executing the main query
Set @sql = N'Select Top 1 @CurWO As CurrentL' + @Col + N'WorkOrder,' + -- @CurWO from last query
N' L' + @Col + N'TE AS CurrentL' + @Col + N'TE,' +
N' L' + @Col + N'TF AS CurrentL' + @Col + N'TF,' +
...
N' From WB.dbo.Line' + @Col +
N' Where L' + @Col + N'WO = @CurWO' +
N' Order By L' + @Col + N'Time Desc'
-- For diagnosing the inevitable errors
Print @sql
Set @params = N'@CurWO int'
Exec sp_executesql @sql, @params, @CurWO