我编写了一个名为FooUpsert
的存储过程,用于在各种表中插入和更新数据。它需要许多数字和字符串参数来提供数据。这个程序很好,我不想修改它。
接下来,我正在编写另一个存储过程,将服务器作为一种批量插入/更新。
程序以原子事务的形式进行工作,这一点非常重要。一些数据被插入/更新是不可接受的,有些则不是。
在我看来,这样做的恰当方法是建立一个表值程序,比如说FooUpsertBulk
。我开始使用table参数编写此存储过程,该参数保存与传递给FooUpsert
的数据类似的数据,我的想法是我可以一次读取一行并调用FooUpsert
中的值每一行。我意识到这可能不是最好的做法,但是FooUpsert
已经写好了,加FooUpsertBulk
每天最多会运行几次。
问题是在FooUpsertBulk
中,我不知道如何迭代行并将每行中的值作为参数传递给FooUpsert
。我确实知道我可以更改FooUpsert
以接受表值参数,但我不想重写FooUpsert
。
你们其中一个SQL忍者可以告诉我该怎么做吗?
我的SQL服务器是MS-SQL 2008。
答案 0 :(得分:0)
将各种查询包装到显式事务中(即BEGIN TRAN
... COMMIT
或ROLLBACK
)会使所有查询成为原子操作。你可以:
从应用程序代码启动事务(假设应用程序代码调用FooUpsert
),因此也必须处理提交和回滚。这仍然会留下许多小的操作,但只需要一个事务,不需要更改代码。
在proc中启动事务,在TRY / CATCH中包含的循环中调用FooUpsert
,以便在FooUpsert
的任何调用失败时处理ROLLBACK。
将代码从FooUpsert
复制到新的FooUpsertBulk
,从应用代码接受TVP并将所有内容作为基于集合的操作处理。调整FooUpsertBulk
中的每个查询以处理各种输入参数,以便在TVP加入查询后从TVP表变量中获取字段。在FooUpsert
正常工作之前,请保持FooUpsertBulk
。