进行数百个数据库更新的正确方法?

时间:2019-05-13 13:27:33

标签: sql tsql transactions sql-update

我有一个功能,可以每分钟查询Google BigQuery,并且我想使用BigQuery结果来更新另一个关系数据库中的行。

我试图做这样的事情:

NameSplit()

这是每个大查询行的BEGIN TRANSACTION UPDATE MyTable SET MyField = BigQueryResult_Row1_MyField WHERE a_id = BigQueryResult_Row1_a_id UPDATE MyTable SET MyField = BigQueryResult_Row2_MyField WHERE a_id = BigQueryResult_Row2_a_id UPDATE MyTable SET MyField = BigQueryResult_Row3_MyField WHERE a_id = BigQueryResult_Row3_a_id . . . UPDATE MyTable SET MyField = BigQueryResult_RowN_MyField WHERE a_id = BigQueryResult_RowN_a_id COMMIT TRANSACTION 语句。我无法将单个UPDATE语句与UPDATE语句组合在一起,因为数据来自BigQuery,而不是来自另一个数据库表。

尝试执行此事务,出现超时错误,所以我想问:这是一次执行数百次更新的正确方法吗?在某些情况下,一次甚至可能有数千次更新。我怎样才能更好地做到这一点?

2 个答案:

答案 0 :(得分:2)

雷纳特的答案很好。但是更通俗的写作方式是使用values()

UPDATE t 
        SET MyField = v.MyField       
    FROM MyTable t JOIN
         (VALUES ('BigQueryResult_Row1_MyField', 'BigQueryResult_Row1_a_id'),
                 ('BigQueryResult_Row2_MyField', 'BigQueryResult_Row2_a_id'),
                 ('BigQueryResult_Row3_MyField', 'BigQueryResult_Row3_a_id'),
                 ('BigQueryResult_RowN_MyField', 'BigQueryResult_RowN_a_id')
         ) v(MyField, a_id)
        ON v.a_id = t.a_id;

通常,在您打算使用UNION时使用UNION ALL是一个坏主意-因为UNION会导致删除重复项的开销。在这种情况下,表构造器无论如何都是更简单的解决方案。

答案 1 :(得分:0)

这样的查询是否没有超时(使用建议的@JohnHC临时表)?

BEGIN TRANSACTION

;WITH UpdateTempTable AS (
    SELECT 'BigQueryResult_Row1_MyField' As MyField, 'BigQueryResult_Row1_a_id' AS a_id
    UNION SELECT 'BigQueryResult_Row2_MyField', 'BigQueryResult_Row2_a_id'
    UNION SELECT 'BigQueryResult_Row3_MyField', 'BigQueryResult_Row3_a_id'
    UNION SELECT 'BigQueryResult_RowN_MyField', 'BigQueryResult_RowN_a_id'
  ) UPDATE MyTable 
        SET MyTable.MyField = UpdateTempTable.MyField       
    FROM MyTable 
        JOIN UpdateTempTable ON UpdateTempTable.a_id = MyTable.a_id;

COMMIT TRANSACTION