Инициализировать таблицу с перечисленными данными - PullRequest
0 голосов
/ 22 октября 2019

Я хотел бы инициализировать таблицу с перечисляемыми данными, такими как

| x | y | z | domain | 
|---|---|---|--------|
| 1 | 1 | 1 | a.com  | 
| 1 | 2 | 1 | a.com  | 
| 1 | 3 | 1 | a.com  |

Запустив хранимую процедуру, такую ​​как:

exec init_table 10, 10, 1

Некоторые таблицы выглядят как

| i | domain | 
|---|--------|
| 1 | a.com  |
| 2 | b.com  |

У меня есть следующее ...

-- Set z to default if `null` is passed in
if (@num_coordinate_z is null) begin set @num_coordinate_z = 1 end

-- Initialize counters for loop
declare @x int = 1, @y int = 1, @z int = 1, @d int = 1
declare @num_domains int = (select distinct count(domain) from 
someDb..someTable)

while (@x <= @num_coordinate_x) begin
  while (@y <= @num_coordinate_y) begin
    while (@z <= @num_coordinate_z) begin
      while (@d <= @num_domains)      begin

        insert into configMotorsTest (
          coordinate_x,
          coordinate_y,
          coordinate_z,
          domain
        ) values (
          @x,
          @y,
          @z,
          (select [domain] from someDb..someTable where [i] = @d)
        )

        set @d = @d + 1

      end 
      set @x = @x + 1
     end
     set @y = @y + 1
   end
   set @z = @z + 1
 end

Но это только запись одной записи.

Как бы я инициализировал (10, 10, 1, 2) (x,y, z, domain) таблица с хранимой процедурой exec?

1 Ответ

2 голосов
/ 22 октября 2019

Это гораздо лучше подходит для подсчета. Цикл WHILE - худший способ сделать это. Это очень медленно.

Если у вас есть таблица доменных адресов, то вы можете просто сделать что-то вроде:

WITH Tally AS(
    SELECT N
    FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10))N(N))
SELECT N1.N AS x,
       N2.N AS y,
       N3.N AS z,
       D.Domain
FROM dbo.DomainTable D
     CROSS JOIN N N1
     CROSS JOIN N N2
     CROSS JOIN N N3;

Это создаст 1000 (10 * 10 * 10) строк длякаждый адрес электронной почты, с вариациями x, y и z.

. Для более «динамического» подхода:

DECLARE @x int = 10,
        @y int = 10,
        @z int = 1;

DECLARE @m int = (SELECT MAX(V.N) FROM (VALUES(@x),(@y),(@z))V(N));

WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
    SELECT TOP (@m)
           ROW_NUMBER () OVER (ORDER BY (SELECT NULL)) AS I
    FROM N N1, N N2, N N3, N N4) --this'll create 10,000 rows
SELECT T1.I AS x,
       T2.I AS y,
       T3.I AS z,
       D.Domain
FROM dbo.DomainTable D
     CROSS JOIN Tally T1
     CROSS JOIN Tally T2
     CROSS JOIN Tally T3
WHERE T1.I <= @x
  AND T2.I <= @y
  AND T3.I <= @z;

Если @x, @y и @z имели значение 1000, тогда это создаст 1000 ^ 3 (1 000 000 000) строк, и он принимает значение до 10 000.

Однако я не рекомендую ни на одну секундучто вы действительно пытаетесь создать более 1 миллиона строк за один раз;это просто заполнит ваш журнал транзакций и, вероятно, приведет к сбою.

...