【问题标题】:Using row count from a temporary table in a while loop SQL Server 2008在while循环SQL Server 2008中使用临时表中的行数
【发布时间】:2012-10-11 15:50:05
【问题描述】:

我正在尝试在 SQL Server 2008 中创建一个将临时表中的数据插入到已经存在的表中的过程。我想我已经弄清楚了,我只是遇到了循环问题。我需要临时表中的行数来确定循环何时结束。

我尝试过以两种不同的方式使用@@ROWCOUNT;在 WHILE 语句中单独使用它,并创建一个变量以在第一个循环完成时尝试保存该值(参见下面的代码)。

这些方法都没有奏效,我现在不知道该怎么做。在这种情况下是否可以使用@@ROWCOUNT,还是有其他更好的方法?

CREATE PROCEDURE InsertData(@KeywordList varchar(max))
AS
BEGIN

--create temp table to hold words and weights
CREATE TABLE #tempKeywords(ID int NOT NULL, keyword varchar(10) NOT NULL); 

DECLARE @K varchar(10), @Num int, @ID int

SET @KeywordList= LTRIM(RTRIM(@KeywordList))+ ','
SET @Num = CHARINDEX(',', @KeywordList, 1)
SET @ID = 0

--Parse varchar and split IDs by comma into temp table
IF REPLACE(@KeywordList, ',', '') <> ''
BEGIN
    WHILE @Num > 0
    BEGIN
        SET @K= LTRIM(RTRIM(LEFT(@KeywordList, @Num - 1)))
        SET @ID = @ID + 1
        IF @K <> ''
        BEGIN
            INSERT INTO #tempKeywords VALUES (@ID, @K) 
        END
        SET @KeywordList = RIGHT(@KeywordList, LEN(@KeywordList) - @Num)
        SET @Num = CHARINDEX(',', @KeywordList, 1)
        --rowcount of temp table
        SET @rowcount = @@ROWCOUNT
    END
END

--declaring variables for loop
DECLARE @count INT
DECLARE @t_name varchar(30)
DECLARE @key varchar(30)
DECLARE @key_weight DECIMAL(18,2)
--setting count to start from first keyword
SET @count = 2
--setting the topic name as the first row in temp table
SET @t_name = (Select keyword from #tempKeywords where ID = 1)
--loop to insert data from temp table into Keyword table
WHILE(@count < @rowcount)
    BEGIN
        SET @key = (SELECT keyword FROM #tempKeywords where ID = @count)
        SET @key_weight = (SELECT keyword FROM #tempKeywords where ID = @count+2)
        INSERT INTO Keyword(Topic_Name,Keyword,K_Weight)
        VALUES(@t_name,@key,@key_weight)
        SET @count= @count +2
    END 
--End stored procedure  
END

【问题讨论】:

  • 为什么还需要WHILE 循环? SQL 是一个基于集合的系统——你应该考虑数据集而不是使用RBAR(逐行痛苦)处理方法.....
  • 老实说,这是我能想到的唯一方法。我尝试了其他没有成功的方法,这是接近工作的唯一方法。
  • 首先解决您的第一个问题 - 在 SQL Server 中搜索并找到 Split 函数的各种实现非常容易。您只需要一个允许您识别值的顺序的方法(因为它们是成对的值)。 this 和其他任何人一样好,就目前而言。并且,请记住责备您的讲师以最糟糕的方式传递这些参数。
  • 别担心,我会的。他整个学期都很没用,我一定会提到这一点,还有其他一直困扰着我的事情!我学习的第一个编码语言是 Java,最近几个月我才开始学习 SQL,所以我的第一直觉是循环遍历内容,即使没有必要。感谢您为我指明正确的方向。

标签: sql-server sql-server-2008 while-loop temp-tables rowcount


【解决方案1】:

解决问题的第二部分:

INSERT INTO Keyword(Topic_Name,Keyword,K_Weight)
SELECT tk1.keyword, tk2.keyword, tk3.keyword
FROM
    #tempKeywords tk1
        cross join
    #tempKeywords tk2
        inner join
    #tempKeywords tk3
        on
           tk2.ID = tk3.ID - 1
WHERE
    tk1.ID = 1 AND
    tk2.ID % 2 = 0

(此代码应替换您当前脚本中 --declaring variables for loop 注释之后的所有内容)

【讨论】:

    【解决方案2】:

    你可以改变:

    WHILE(@count < @rowcount)
    

    WHILE(@count < (select count(*) from #tempKeywords))
    

    但就像 marc_s 评论的那样,你应该能够在没有 while 循环的情况下做到这一点。

    【讨论】:

      【解决方案3】:

      我会考虑重新处理您的查询,看看您是否可以以基于集合的方式而不是逐行执行此操作。

      我不确定我是否完全遵循了您想要实现的目标,但我很想查看 ROW_NUMBER() 函数来设置临时表的 ID。与递归 CTE 一起使用,例如 this answer 中所示,您可以获得每个非空修剪单词的 id。一个例子是这样的;

      DECLARE @KeywordList varchar(max) = 'TEST,WORD, ,,,LIST, SOME , WITH, SPACES'
      
      CREATE TABLE #tempKeywords(ID int NOT NULL, keyword varchar(10) NOT NULL) 
      
      ;WITH kws (ord, DataItem, Data) AS(
          SELECT CAST(1 AS INT), LEFT(@KeywordList, CHARINDEX(',',@KeywordList+',')-1) ,
          STUFF(@KeywordList, 1, CHARINDEX(',',@KeywordList+','), '') 
          union all
          select ord + 1, LEFT(Data, CHARINDEX(',',Data+',')-1),
              STUFF(Data, 1, CHARINDEX(',',Data+','), '')
              from kws
              where Data > ''
      ), trimKws(ord1, trimkw) AS (
          SELECT ord, RTRIM(LTRIM(DataItem)) 
          FROM kws
      ) 
      INSERT INTO #tempKeywords (ID, keyword) 
      SELECT ROW_NUMBER() OVER (ORDER BY ord1) as OrderedWithoutSpaces, trimkw 
      FROM trimKws WHERE trimkw <> '' 
      
      SELECT * FROM #tempKeywords
      

      我不完全理解您要通过查询的第二部分来实现什么,但您可以在此基础上使其其余部分正常工作。看起来你至少可以在没有 while 语句的情况下做你想做的事。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-28
        • 2018-10-28
        • 2010-12-25
        • 2013-08-18
        • 2014-03-11
        • 2015-12-30
        • 2014-02-10
        • 2018-02-24
        相关资源
        最近更新 更多