我很难跟踪Azure Stream Analytics中的投射错误。输入数据来自Azure IoT Hub。这是我的查询代码:
-- Create average data from raw data
WITH
AverageSensorData AS
(
SELECT
[Node],
[SensorType],
udf.round(AVG([Value]), 2) AS [Value],
MAX(TRY_CAST([Timestamp] AS DateTime)) AS [Timestamp]
FROM [SensorData]
WHERE TRY_CAST([Timestamp] AS DateTime) IS NOT NULL
GROUP BY
[Node],
[SensorType],
TumblingWindow(minute, 2)
)
-- Insert average data into PowerBI-Output
SELECT
[Node],
[SensorType]
[Value],
[Timestamp],
DATETIMEFROMPARTS(
DATEPART(yy, [Timestamp]),
DATEPART(mm, [Timestamp]),
DATEPART(dd, [Timestamp]),
0, 0, 0, 0) AS [Date]
INTO [SensorDataAveragePowerBI]
FROM [AverageSensorData]
虽然大部分时间(至少对几百或几千个输入实体)运行良好,但它最终会失败。在打开诊断日志之后,我能够在相应的执行日志中找到以下错误消息(实际上它是JSON格式,为了便于阅读我清理了一点):
消息:处理事件时发生运行时异常, - 指定的强制转换无效。 OutputSourceAlias:averagesensordata;键入:SqlRuntimeError,相关ID:49938626-c1a3-4f19-b18d-ee2c5a5332f9
这里有一些可能导致错误的JSON输入:
[
{
"Date": "2017-04-27T00:00:00.0000000",
"EventEnqueuedUtcTime": "2017-04-27T07:53:52.3900000Z",
"EventProcessedUtcTime": "2017-04-27T07:53:50.6877268Z",
"IoTHub": {
/* Some more data that is not being used */
},
"Node": "IoT_Lab",
"PartitionId": 0,
"SensorType": "temperature",
"Timestamp": "2017-04-27T09:53:50.0000000",
"Value": 21.06
},
{
"Date": "2017-04-27T00:00:00.0000000",
"EventEnqueuedUtcTime": "2017-04-27T07:53:53.6300000Z",
"EventProcessedUtcTime": "2017-04-27T07:53:52.0157515Z",
"IoTHub": {
/* Some more data that is not being used */
},
"Node": "IT_Services",
"PartitionId": 2,
"SensorType": "temperature",
"Timestamp": "2017-04-27T09:53:52.0000000",
"Value": 27.0
}
]
第一个条目是最后一个条目,所以第二个条目可能是破坏一切的条目。不过,我不确定,在这里看不到任何可疑的价值观。如果我在Azure门户中将其作为测试数据上载,则不会产生任何错误。
上面的查询明确地使用了[Timestamp]
列的强制转换。但由于我使用TRY_CAST,我不会指望任何投射错误:
如果转换成功,则返回强制转换为指定数据类型的值;否则,返回null。
正如我所说,错误只会偶尔出现一次(有时是20分钟后,有时是几个小时后),并且无法明确再现。有没有人知道错误的来源或是否有可能获得更详细的错误信息?
提前多多感谢。
更新:以下是udf.round
功能的来源:
function main(value, decimalPlaces) {
if (typeof(value) === 'number'){
var decimalMultiplier = 1;
if (decimalPlaces){
decimalMultiplier = Math.pow(10, decimalPlaces);
}
return Math.round(value * decimalMultiplier) / decimalMultiplier
}
return value;
}
不幸的是,自从我写这篇文章以来已经有一段时间了,所以我不能百分之百地确定为什么我写这个代码。但我记得的一件事是,我所分析的所有消息在相应字段中始终包含有效数字。我仍然认为这个函数很有可能对我的问题负责。