SQL Server: неожиданное поведение во время использования INSERT INTO - PullRequest
0 голосов
/ 21 мая 2018

Полагаю, это будет очень просто для любого, кто знает программирование на SQL ...

SQLFiddle

Вот код, который я выполняю противбаза данных:

DECLARE @maxCounter int
-- Used to get the maximum bound number for my loop, basically what is the highest number of records. Tested, seems to work as expected.
SET @maxCounter = (SELECT TOP 1 COUNT(SN)
                   FROM TestResults 
                   WHERE Type = 'EX'
                   GROUP BY SN
                   ORDER BY COUNT(SN) DESC)

CREATE TABLE #Info
(
    DLoc VARCHAR(500),
    DCode VARCHAR(500),
    Dobs VARCHAR(500)
)

DECLARE @counter INT
SET @counter = 1

WHILE @counter <= @maxCounter 
BEGIN
    INSERT INTO #Info (DLoc) 
    VALUES ('Location_' + CAST(@counter AS VARCHAR(16)))

    INSERT INTO #Info (DCode) 
    VALUES ('Code_' + CAST(@counter AS VARCHAR(16)))

    INSERT INTO #Info (Dobs) 
    VALUES ('Observation_' + CAST(@counter AS VARCHAR(16)))

    SET @counter = @counter + 1
END

SELECT * FROM #Info;

DROP TABLE #Info;

Если вы видите в коде какие-то странные вещи, то это потому, что я начинающий и не знаю ничего лучше.

Ожидаемый вывод цикла while:

+------------+---------+---------------+
| defLoc     | defCode | obs           |
+------------+---------+---------------+
| Location_1 | Code_1  | Observation_1 |
| Location_2 | Code_2  | Observation_2 |
| Location_3 | Code_3  | Observation_3 |
+------------+---------+---------------+

Неожиданный результат вывода:

defLoc           | defCode     | obs           |
-----------------+-------------+---------------|
Location_1       |             |               |
                 | Code_1      |               |
                 |             | Observation_1 |
Location_2       |             |               |
                 | Code_2      |               |
                 |             | Observation_2 |
Location_3       |             |               |
                 | Code_3      |               |
                 |             | Observation_3 |

Понятия не имею, откуда появляются пустые ячейки ...

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Вы можете вставить каждую строку с 3 различными значениями столбца с помощью одного оператора вставки в цикле:

WHILE @counter <= @maxCounter
BEGIN
    INSERT INTO #Info (DLoc,DCode,Dobs)
    VALUES (
          'Location_' + CAST(@counter AS VARCHAR(16))
        , 'Code_' + CAST(@counter AS VARCHAR(16))
        , 'Observation_' + CAST(@counter AS VARCHAR(16))
        );
    SET @counter = @counter + 1;
END;

В качестве альтернативы, вы можете вставить все строки одновременно в одном операторе INSERT...SELECT, используя подсчеттаблица в качестве источника.Если у вас нет счетной таблицы, вы можете использовать CTE для генерации набора чисел.В приведенном ниже примере используется CTE с ROW_NUMBER(), который может быть расширен при необходимости.

WITH 
     t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
    ,t1k AS (SELECT 0 AS n FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c)
    ,t1m AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num FROM t1k AS a CROSS JOIN t1k AS b CROSS JOIN t1k AS c)
INSERT INTO #Info (DLoc,DCode,Dobs)
SELECT
          'Location_' + CAST(num AS VARCHAR(16))
        , 'Code_' + CAST(num AS VARCHAR(16))
        , 'Observation_' + CAST(num AS VARCHAR(16))
FROM t1m
WHERE num <= @maxCounter;

В SQL Server операции на основе множеств обычно опережают процедурные циклические конструкции на порядки.

0 голосов
/ 21 мая 2018

Вам необходимо использовать ONE INSERT для каждой итерации и указывать все три столбца и их значения за один раз:

WHILE @counter <= @maxCounter 
BEGIN
    INSERT INTO #Info (DLoc, DCode, Dobs) 
    VALUES ('Location_' + CAST(@counter AS VARCHAR(16)),  
            'Code_' + CAST(@counter AS VARCHAR(16)),
            'Observation_' + CAST(@counter AS VARCHAR(16))
           )

    SET @counter = @counter + 1
END

Каждый INSERT вставит всю строку - указанное вами значение будет вставлено в указанный вами столбец, но другие столбцы все останутся NULL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...