【问题标题】:SQL iterating over a list to call EXEC on each itemSQL 遍历列表以对每个项目调用 EXEC
【发布时间】:2009-05-13 18:57:57
【问题描述】:

尝试概括我的问题... 我想为 SELECT 语句返回的每个结果执行一个存储过程。

心理上我想尝试类似的东西 EXEC myStoredProc (SELECT id FROM sometable WHERE cond = @param)

与我的具体案例有关的更多详细信息... 我有一个 SaaS 应用程序。我想从系统中删除一个租户。在我可以删除租户之前,我必须删除与该租户关联的数据库中的所有记录。

租户拥有诸如表单之类的项目,其中包含许多不同类型的字段。我已经有一个存储过程,可以删除表单及其所有关联项目(如字段)。出于维护原因(即不想重复确定记录和表单之间的依赖关系和关联的逻辑),我只想为属于租户的每个表单调用该 StoredProc。

我可以通过运行类似...的查询来检索表单列表 从 Forms WHERE Tenant = @TenantId 中选择 formId

我想要对查询结果执行的操作是执行我的 Delete_Form 存储过程。

我该怎么做?

【问题讨论】:

    标签: sql stored-procedures loops iteration exec


    【解决方案1】:

    在您无法控制外键且无法进行级联删除的情况下,您可以创建一个游标以循环并为每个外键执行存储的过程。

    declare @formID int
    declare FormsCursor cursor fast_forward for Select formId FROM Forms WHERE Tenant = @Tenant
    
    open FormsCursor
    
    fetch next from FormsCursor into @formID
    
    while @@fetch_status = 0
    begin
    
       exec Delete_Form @formID
    
       fetch next from FormsCursor into @formID
    
    end
    
    close FormsCursor
    deallocate FormsCursor
    

    【讨论】:

      【解决方案2】:

      您可以打开级联删除,删除父记录将删除与其关联的所有子记录。

      如果不是,您将不得不创建一个cursor(该链接适用于 sql server,但我假设其他 RDBMS 的游标是相似的)并循环遍历每个结果,取出表单 ID 并执行[Delete_Field_Procedure] 为每个。

      【讨论】:

      • 感谢您的回复凯文。我觉得级联删除发生了太多“魔术”,有些事情可能会意外消失。所以我要使用你提到的游标:)谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-11
      • 1970-01-01
      • 1970-01-01
      • 2017-05-27
      • 1970-01-01
      相关资源
      最近更新 更多