简体   繁体   English

如何将值从存储过程中的表参数传递到另一个存储过程?

[英]How to pass values from a table parameter in a Stored Procedure to another Stored Procedure?

I've written a stored procedure called FooUpsert that inserts and updates data in various tables. 我编写了一个名为FooUpsert的存储过程,该过程可以在各种表中插入和更新数据。 It takes a number of numeric and string parameters that provide the data. 它需要许多提供数据的数字和字符串参数。 This procedure is in good shape and I don't want to modify it. 此过程状态良好,我不想修改它。

Next, I'm writing another stored procedure that servers as a sort of bulk insert/update. 接下来,我正在编写另一个存储过程,该存储过程作为一种批量插入/更新进行服务器。

It is of tantamount importance that the procedure do its work as an atomic transaction. 程序作为原子事务来完成其工作,这一点极为重要。 It would be unacceptable for some data to be inserted/updated and some not. 插入/更新某些数据而不插入或更新某些数据将是不可接受的。

It seemed to me that the appropriate way of doing this would be to set up a table-valued procedure, say FooUpsertBulk . 在我看来,执行此操作的适当方法是建立一个表值过程, FooUpsertBulk I began to write this stored procedure with a table parameter that holds data similar to what is passed to FooUpsert , the idea being that I can read it one row at a time and invoke FooUpsert for the values in each row. 我开始使用表参数编写此存储过程,该表参数保存的数据类似于传递给FooUpsert ,其想法是我可以一次读取一行并为每行中的值调用FooUpsert I realize that this may not be the best practice for this, but once again, FooUpsert is already written, plus FooUpsertBulk will be run at most a few times a day. 我知道这可能不是我们的最佳做法,但再次, FooUpsert已经写好,加上FooUpsertBulk将至多一天几次运行。

The problem is that in FooUpsertBulk , I don't know how to iterate the rows and pass the values in each row as parameters to FooUpsert . 问题是在FooUpsertBulk ,我不知道如何迭代行并将每行中的值作为参数传递给FooUpsert I do realize that I could change FooUpsert to accept a table-values parameter as well, but I don't want to rewrite FooUpsert . 我确实意识到我也可以更改FooUpsert来接受一个表值参数,但是我不想重写FooUpsert

Can one of you SQL ninjas out there please show me how to do this? 你们当中的SQL忍者可以请教我如何做到这一点吗?

My SQL server is MS-SQL 2008. 我的SQL服务器是MS-SQL 2008。

Wrapping various queries into an explicit transaction (ie BEGIN TRAN ... COMMIT or ROLLBACK ) makes all of it an atomic operation. 将各种查询包装到显式事务中(即BEGIN TRAN ... COMMITROLLBACK )使所有查询成为原子操作。 You can: 您可以:

  • start the transaction from the app code (assuming that FooUpsert is called by app code) and hence have to deal with the commit and rollback there as well. 从应用程序代码开始事务(假设FooUpsert被应用程序代码调用),因此也必须在该处处理提交和回滚。 this still leaves lots of small operations, but a single transaction and no code changes needed. 这仍然留下了许多小操作,但是只需要一个事务就不需要更改代码。

  • start the transaction in a proc, calling FooUpsert in a loop that is contained in a TRY / CATCH so that you can handle the ROLLBACK if any call to FooUpsert fails. 在proc中启动事务,并在TRY / CATCH中包含的循环中调用FooUpsert ,以便在对FooUpsert任何调用失败时可以处理ROLLBACK。

  • copy the code from FooUpsert into a new FooUpsertBulk that accepts a TVP from the app code and handles everything as set-based operations. 将代码从FooUpsert复制到新的FooUpsertBulk ,该FooUpsertBulk从应用程序代码接受TVP并将所有内容作为基于集合的操作进行处理。 Adapt each of the queries in FooUpsertBulk from handling various input params to getting fields from the TVP table variables once the TVP is joined into the query. 将TVP加入查询后,使FooUpsertBulk每个查询从处理各种输入参数变为从TVP表变量获取字段。 Keep FooUpsert in place until FooUpsertBulk is working. 保持FooUpsert到位,直到FooUpsertBulk工作为止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM