Вы можете просто переписать вашу вставку, как показано ниже внутри курсора:
INSERT INTO cursor_copied (id, name, amount, date)
VALUES (@ID, @Name, @Amount, @Date),
(@ID, @Name, @Amount, @Date)
НО выбранное вами решение может быть не лучшим решением для такого рода проблем.Если вас интересуют другие решения, пожалуйста, прочитайте также следующие истории.
Решение 1
см. @ GordonLinoff's ответ
Решение 2
Давайте рассмотрим проблему шаг за шагом:
Сначала предположим, что есть две таблицы, подобные этой:
CREATE TABLE t1(Id INT, Name NVARCHAR(50), Amount DECIMAL(18,0), Date NVARCHAR(50))
GO
CREATE TABLE t1_copy(Id INT, Name NVARCHAR(50), Amount DECIMAL(18,0), Date NVARCHAR(50))
Затем я полагаю, что я вставил следующие записи в t1
:
INSERT INTO t1 VALUES
(1,'A', 2000,'2008-03-15 18:15:43.000'),
(2,'B', 3000,'2008-03-15 18:15:43.000'),
(3,'C', 4000,'2008-03-15 18:15:43.000')
Далее мне нужно подумать о запросе, который поможет мне создать дублированные записи.У меня есть множество доступных опций, таких как Cross Apply
, как упоминал @GordonLinoff.Другой способ - использовать UNION ALL
следующим образом:
SELECT t1.Id,
t1.Name,
t1.Amount,
t1.Date FROM dbo.t1
UNION ALL
SELECT Id,
Name,
Amount,
Date FROM dbo.t1;
Этот запрос даст желаемый результат, и мне нужно просто вставить их в таблицу назначения следующим образом:
INSERT INTO dbo.t1_copy(Id,Name,Amount,Date)
SELECT t1.Id,
t1.Name,
t1.Amount,
t1.Date FROM dbo.t1
UNION ALL
SELECT Id,
Name,
Amount,
Date FROM dbo.t1;
Очевидно, что перед вставкой в таблицу может потребоваться обратить внимание на столбец Primary Key
или Identity
, если он существует!
Решение 3
Вы можете использовать GO
!вот так:
INSERT INTO dbo.t1_copy(Id,Name,Amount,Date)
SELECT Id,Name,Amount,Date FROM dbo.t1
GO 2
Это не то, что я бы порекомендовал, потому что GO - это пакетный сепаратор, и он доставит вам неприятности.Также вышеупомянутый запрос будет выполнен как две отдельные транзакции, что снова может стать проблемой!
Решение 4
Вы можете использовать оператор OUTPUT
.однако из-за сложности, опять же, я не рекомендую это.Например:
INSERT INTO dbo.t1_copy(Id,Name,Amount,Date)
SELECT * FROM(
INSERT INTO dbo.t1_copy(Id,Name,Amount,Date)
OUTPUT Inserted.id, Inserted.Name, Inserted.Amount, Inserted.Date
SELECT Id,Name,Amount,Date FROM dbo.t1) AS k
Как насчет использования курсора?
@ GordonLinoff упомянул точку ошибки использования курсора в этом сценарии, однако еслиВы настаиваете на использовании курсора, вам нужно объявить курсор в режиме Fast_Forward
.Объявление его в режиме SCROLL
не поможет вам и снизит общую производительность запроса!
DECLARE IDs CURSOR FAST_FORWARD FOR ...
Сравнение производительности:
Если мы просто посмотрим на план выполнения вышеупомянутых решений, мы увидим, что Решение 1 имеет лучший выход производительностипо сравнению с другим решением.На моем ПК вывод плана выполнения выглядит следующим образом:
Solution 1 ====================> Subtree Cost: 0.0133
Solution 2 ====================> Subtree Cost: 0.0165
Solution 3 ====================> Subtree Cost: 0.0132*2=0.0264
Solution 4 ====================> Subtree Cost: 0.0232
Cursor in SCROLL mode =========> Subtree Cost: 0.0332
Cursor in Fast_Forward mode ===> Subtree Cost: 0.0203
Эти цифры могут отличаться на вашем ПК!