我可以在没有id列的情况下迭代sql中的表吗?

时间:2018-05-07 11:17:31

标签: sql sql-server loops while-loop

假设我有一个包含两列的表(例如四分之一和一年),我想根据这两列的值创建第三列。有没有办法在没有或创建标识列的情况下使用while循环迭代表?

那么举个例子,假设我有这些行:

Quarter    Year    Datetimes  
---------- ------  --------------  
1          2018    null  
2          2018    null  
3          2018    null  

我想更新第3列并制作它:

Quarter    Year    Datetimes  
---------- ------  --------------  
1          2018    2018-03-31 00:00:00.000  
2          2018    2018-06-30 00:00:00.000  
3          2018    2018-09-30 00:00:00.000  

我知道如何进行转换,公式如下:

DATEADD(YEAR, @theYear - 1900, DATEADD(QQ, @TheQuarter, -1)).   

问题是我想要更新表,这意味着我想要添加新信息,而不仅仅是显示第3列作为输出的内容。

2 个答案:

答案 0 :(得分:4)

嗯,是的,您可以使用不带#define LINE_SIZE 300 void combine(void) { DIR *d; FILE *fin; FILE *fout; struct dirent *dir; char headers[LINE_SIZE]; char values[LINE_SIZE]; short flagHeader = 1; fout = fopen("results-c-new.txt", "wb"); chdir("runs"); d = opendir("."); if (d) { while ((dir = readdir(d)) != NULL) { if ((strstr(dir->d_name, "Hs")) && (strstr(dir->d_name, ".txt")) ) { fin = fopen(dir->d_name, "rb"); fgets(headers, LINE_SIZE, fin); fgets(values, LINE_SIZE, fin); if (flagHeader) { flagHeader = 0; fputs(headers, fout); } fputs(values, fout); fclose(fin); } } closedir(d); fclose(fout); } } 列的游标遍历表格。

但出于以下几个原因,这是一个非常糟糕的主意:

  1. 一般来说,你应该避免使用游标。
  2. 您的表应该都已定义主要ID。
  3. 您可以使用基于集合的查询执行所需操作。

答案 1 :(得分:1)

CURSOR对象专门用于迭代任何行集,由SELECT确定。您的SELECT可以像您想要的那样复杂,并且不要求行是唯一的。

基本语法类似于以下示例:

IF OBJECT_ID('tempdb..#Dates') IS NOT NULL
    DROP TABLE #Dates

CREATE TABLE #Dates (
    Month INT,
    Year INT)

INSERT INTO #Dates (
    Month,
    Year)
VALUES
    (1, 2018),
    (5, 2018),
    (10, 2020),
    (10, 2020) -- Repeated value

DECLARE @c_Month INT
DECLARE @c_Year INT

DECLARE DateCursor CURSOR FOR
    SELECT
        D.Month,
        D.Year
    FROM
        #Dates AS D
    ORDER BY
        D.Year,
        D.Month

OPEN DateCursor

FETCH NEXT FROM DateCursor INTO 
    @c_Month,
    @c_Year

WHILE @@FETCH_STATUS = 0
BEGIN

    SELECT
        Month = @c_Month,
        Year = @c_Year,
        CalculatedColumn = DATEFROMPARTS(@c_Year, @c_Month, 1)

    FETCH NEXT FROM DateCursor INTO 
        @c_Month,
        @c_Year

END

CLOSE DateCursor
DEALLOCATE DateCursor

/*
Results:

    Month       Year        CalculatedColumn
    ----------- ----------- ----------------
    1           2018        2018-01-01

    Month       Year        CalculatedColumn
    ----------- ----------- ----------------
    5           2018        2018-05-01

    Month       Year        CalculatedColumn
    ----------- ----------- ----------------
    10          2020        2020-10-01

    Month       Year        CalculatedColumn
    ----------- ----------- ----------------
    10          2020        2020-10-01

*/

话虽如此,请尽量避免使用游标,因为关系数据库的设计和优化是为了使用集合。游标应该是你的最后手段。

编辑:您根本不需要光标:

UPDATE T SET
    YourColumn = DATEADD(YEAR, T.Year - 1900, DATEADD(QQ, T.Quarter, -1))
FROM
    YourTable AS T