Azure 使用流分析按条件在sql表中插入/更新iothub中的引用数据

Azure 使用流分析按条件在sql表中插入/更新iothub中的引用数据,azure,azure-sql-database,cql,azure-iot-hub,azure-stream-analytics,Azure,Azure Sql Database,Cql,Azure Iot Hub,Azure Stream Analytics,我在azure上工作,有一个sql transact数据库,有两个表和一个iotHub,它接收来自多个设备的数据。我必须检查数据库中当前是否存在数据,如果不存在,则将其存储,否则将更新表中的旧数据 表一如下: id | key1 ------------- 1 | abc 2 | def 3 | ghi 表二如下: id | id_tableOne | key2 | something -----------------

我在azure上工作,有一个sql transact数据库,有两个表和一个iotHub,它接收来自多个设备的数据。我必须检查数据库中当前是否存在数据,如果不存在,则将其存储,否则将更新表中的旧数据

表一如下:

id   |   key1
-------------
1    |   abc
2    |   def
3    |   ghi
表二如下:

id    |   id_tableOne  |   key2         |   something
-------------------------------------------------------
77    |   2            |   Emil         |   welcome
78    |   1            |   Emil         |   here I am
79    |   1            |   Hans         |   hello world
来自iotHub的json消息流如下:

{
    "topic": "test",
    "key1": "ghi",
    "data": [{
        "key2": "Emil",
        "something": "lmn"
    },
    {
        "key2": "Hans",
        "something": "hij"
    },
    {
        "key2": "Gerda",
        "something": "xyz"
    }]
}
我想通过json流中的键1从tableOne获取id 我想检查id_tableOne的组合是否来自1。键2存在于 表二 如果确实存在:更新表2中的行-否则:在中插入新行 表二 基于,azure stream Ansystics输入中仅支持EventHub、IoThub和blob存储。因此,您无法使用输出sql数据库筛选条件。因为下面的sql是禁止的

SELECT 
jaysqlserver2.id as id,
jaysqlserver2.id_tableOne as idTableOne,
jaysqlserver2.key2 as key2,
jaysqlserver2.somthing as something
from jsoninput
where jaysqlserver2.id_tableOne = jsoninput.key1 
但是,我为您提供了一个解决方法

首先,您可以平整jsoninput并将其保存到目标sql数据库中的临时表中

SELECT 
    jsoninput.key1, 
    arrayElement.ArrayValue.key2,
    arrayElement.ArrayValue.something
INTO 
    output
FROM jsoninput
CROSS APPLY GetArrayElements(jsoninput.data) AS arrayElement
然后,您可以使用Azure函数时间触发器自动操作sql数据库。请参考以下伪代码:

#r "System.Configuration"
#r "System.Data"
using System.Net;
using System.Configuration;
using System.Data.SqlClient;
using System.Threading.Tasks;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    var str = ConfigurationManager.ConnectionStrings["sqldb_connection"].ConnectionString;
    using (SqlConnection conn = new SqlConnection(str))
    {
        conn.Open();
        var text = "select temp.key1 as key1temp,temp.key2 as key2temp,
t1.id as id1,t1.key1 as key1,
t2.id as id2,t2.id_tableOne as tableOne,t2.key2 as key2,t2.something as something
from dbo.tabletemp as temp
left join dbo.table1 as t1 on temp.key1 = t1.key1
left join dbo.table2 as t2 on t1.id = t2.id_tableOne and temp.key2 = t2.key2
where t1.id is not null";

        SqlCommand sqlComm = new SqlCommand(text, conn);

        SqlDataReader reader = sqlComm.ExecuteReader();

        while(reader.Read())
        {
            string id2 = reader["id2"].ToString();
            if(id2 == null)
            {
                //execute insert sql
            }
            else
            {
                //execute update sql
            }
        }

        var delSql = "delete from dbo.temp";
        //execute delete data in temp table
        ...
    }
}

希望对您有所帮助。如有任何问题,请告诉我。

嘿,杰,谢谢您的回答。是的,你的回答帮助了我!我现在还不能实现它,但我有一个办法!非常感谢!顺便说一句:这种方法是最佳实践吗->我不确定,但我认为存储与其他存储数据相关的数据的要求并不新鲜,不是吗?@eid是的,我认为这是我迄今为止所能想到的最佳方法,如果你采用这个答案,请标记它。非常感谢。