【问题标题】:Execute SQL statements while looping a table在循环表时执行 SQL 语句
【发布时间】:2012-06-28 03:26:41
【问题描述】:

我想创建一个包含几条记录的表,然后为该表中的每条记录运行一组 sql 语句。我会使用表中的数据来设置sql语句中的值。

这应该允许我只编写一次 SQL,然后针对我放入表中的任何数据运行它。

但是,我不知道该怎么做。我应该使用游标来循环表格吗?其他方式?

感谢您能给我的任何帮助或建议。

【问题讨论】:

  • 是的,CURSOR 可以。但是这是否是最好的解决方案取决于你在循环中究竟要做什么(你可能不需要它)。
  • 什么数据库?这听起来更像是存储过程的工作。
  • @bfavaretto 我将放置几个 INSERT 语句来填充一系列表。
  • @Tawnos 是的,所有这些都将存在于存储过程中。我试图避免对存储过程进行 10 次调用并传入 15 个值。除非这只是最好的方法。

标签: sql sql-server


【解决方案1】:

CURSOR 会有与之相关的开销,但它可能是遍历表的好方法。它们不是完全不必要的邪恶,并且有自己的位置。

由于 WilliamB2 提供的信息有限,听起来 CURSOR 集可能是解决此问题的一个很好的解决方案,可以遍历他的数据并生成多个下游 INSERT。

【讨论】:

    【解决方案2】:

    是的,您可以使用光标。你也可以使用while循环

    declare @table as table(col1 int, col2 varchar(20))
    
    declare @col1 int
    declare @col2 varchar(50)
    
    declare @sql varchar(max)
    
    insert into @table
    SELECT col1, col2 FROM OriginalTable
    
    while(exists(select top 1 'x' from @table)) --as long as @table contains records continue
    begin
       select top 1 @col1=col1, @col2=col2 from @table
    
       SET @sql = 'INSERT INTO Table t VALUES('+cast(@col1 as varchar)+')'
    
    
       delete top (1) from @table --remove the previously processed row. also ensures no infinite loop
    end 
    

    我认为光标有附加的开销。

    使用第二种方法,您不会在原始表上工作

    【讨论】:

    • 请注意,在 'SET @sql =' 行,您需要针对您的数据库执行这些语句,或者以某种方式收集它们以供以后执行。另请注意,您在内存中复制 OriginalTable 会产生一些内存开销。
    • 是的,这是真的。但是表格不会在循环时被 CURSOR 锁定。
    【解决方案3】:

    也许您可以使用INSERT...SELECT 代替循环:

    INSERT INTO target_table
    SELECT
        some_col,
        some_other_col,
        'Some fixed value',
        NULL,
        42,
        you_get_the_idea
    FROM source_table
    WHERE source_table.you_get_the_idea = 1
    

    SELECT 上的列应该与目标表的结构相匹配(如果有的话,可以省略像 id 这样的 int/identity pk)。

    如果最好的选择是这个或循环取决于您要在循环内填充多少表。如果只是几个,我通常坚持INSERT...SELECT

    【讨论】:

    • 我实际上并没有将数据从源表插入到目标表中。我正在使用源表中的字段来设置 INSERT 语句中的参数以填充其他表。例如,如果我的源表是我拥有的关于不同类型水果的所有信息,我正在使用它来将一堆关于水果的统计数据插入到另一个表中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-02
    • 1970-01-01
    • 2013-04-13
    • 1970-01-01
    • 2020-11-17
    相关资源
    最近更新 更多