Вставити кілька рядків БЕЗ повторення частини заяви «ВСТАВКА В…»?


536

Я знаю, що робив це раніше років тому, але не можу згадати синтаксис, і не можу його знайти де-небудь через підтягування тонн довідкових статей та статей про "масовий імпорт".

Ось що я хочу зробити, але синтаксис не зовсім правильний ... будь ласка, хтось, хто це робив раніше, допоможіть мені :)

INSERT INTO dbo.MyTable (ID, Name)
VALUES (123, 'Timmy'),
    (124, 'Jonny'),
    (125, 'Sally')

Я знаю, що це близько до правого синтаксису. Мені може знадобитися слово "БУЛК" там, або щось таке, я не можу пригадати. Будь-яка ідея?

Мені це потрібно для бази даних SQL Server 2005. Я спробував цей код безрезультатно:

DECLARE @blah TABLE
(
    ID INT NOT NULL PRIMARY KEY,
    Name VARCHAR(100) NOT NULL
)

INSERT INTO @blah (ID, Name)
    VALUES (123, 'Timmy')
    VALUES (124, 'Jonny')
    VALUES (125, 'Sally')

SELECT * FROM @blah

Я отримую Incorrect syntax near the keyword 'VALUES'.


4
Ваш вище код відмінно просто потрібно додати «» після того, як значення заяви
SaM

4
INSERT INTO @blah (ID, Ім'я), ЗНАЧЕННЯ (123, 'Тіммі'), ЗНАЧЕННЯ (124, 'Джонні'), ЗНАЧЕННЯ (125, 'Саллі')
Сем

1
Просто обережність: ви можете вставити до 1000 рядків лише цим методом. ВСТАВИТИ В # TEST (LWPurchaseOrderID) ЦІННОСТІ (935791), (935933)
Anoop Verma

16
2005 більше не підтримується. Для 2008, 2012 та 2016 років ви можете майже використовувати те, що ви ставите INSERT INTO @blah (ID, Name) VALUES (123, 'Timmy'), (124, 'Jonny'), (125, 'Sally') "VALUES", з’являється лише один раз, і вам знаходяться коми між наборами.
Дж. Кріс Комптон

Відповіді:


328
INSERT INTO dbo.MyTable (ID, Name)
SELECT 123, 'Timmy'
UNION ALL
SELECT 124, 'Jonny'
UNION ALL
SELECT 125, 'Sally'

Для SQL Server 2008 можна зробити це в одному пункті VALUES точно відповідно до твердження у вашому запитанні (вам просто потрібно додати кому для відокремлення кожного виразу значень) ...


10
Це більш ефективно, ніж використання декількох операторів INSERT?
Командир коду

7
@Code Commander: ні, оскільки це довше збирати. Так, у вас є лише одна вставка. Але він відповідає на питання: жодного повторуINSERT table (columnlist)
gbn

3
@VoidKing Я знаю, що це настає через півроку, і ви, можливо, це зрозуміли ще давно, але це дуже просто. Використовуючи selectви створюєте набір зі стовпцями та рядками, а за допомогою проектування ці рядки можна insertредагувати в іншу таблицю з рівною кількістю стовпців. Можна навіть використовувати суміш літералів і значень. Наприклад, при використанні insertз select 'A', ID from ATableкожного разу буде вставлено "A" у перший стовпець, а значення стовпця ID відповідного рядка ATable у другому стовпчику.
MarioDS

1
Це також працює з DB2, який є важливим стороною для тих, хто з нас застряг у застарілій технології. Значення, відокремлені відповіддю через коми, краще мені здається для тих, хто працює в SQL Server 2008 або новіших версіях. ОП може видалити всі "значення", окрім першого, і замінити на,
JPK

1
@PRMan, ви б цього не робили після версії SQL Server 2008. Як уже згадувалося ...
gbn

510

Ваш синтаксис майже працює в SQL Server 2008 (але не в SQL Server 2005 1 ):

CREATE TABLE MyTable (id int, name char(10));

INSERT INTO MyTable (id, name) VALUES (1, 'Bob'), (2, 'Peter'), (3, 'Joe');

SELECT * FROM MyTable;

id |  name
---+---------
1  |  Bob       
2  |  Peter     
3  |  Joe       

1 Коли відповіли на запитання, не стало очевидним, що це питання стосується SQL Server 2005. Я залишаю цю відповідь тут, оскільки я вважаю, що вона все ще актуальна.


Працює в SQL Server 2012
user2601995

27
Сервер 2008 не дозволяє використовувати більше 1000 рядків, вставлених таким чином.
Michael - Де Clay Shirky

1
Що станеться, якщо один набір значень несправний? Чи будуть усі вставки повернуті назад або просто несправний ряд?
netblognet

2
@netblognet Я щойно перевірив, що лише несправні рядки не вставлені (усі інші всі вставлені правильно)
Mauricio Gracia Gutierrez

1
@Michael Це може бути знято stackoverflow.com/a/42703601/5070879
Лукаш

243

Якщо ваші дані вже є у вашій базі даних, ви можете зробити:

INSERT INTO MyTable(ID, Name)
SELECT ID, NAME FROM OtherTable

Якщо вам потрібно жорстко кодувати дані, тоді SQL 2008 та новіші версії дозволяють вам виконати наступні дії ...

INSERT INTO MyTable (Name, ID)
VALUES ('First',1),
('Second',2),
('Third',3),
('Fourth',4),
('Fifth',5)

28

Використовуючи INSERT INTO ... VALUESсинтаксис, як у відповіді Даніеля Вассалло, є одне дратівливе обмеження:

Від MSDN

Максимальна кількість рядків, яку можна побудувати, вставляючи рядки безпосередньо у списку VALUES, - 1000

Найпростіший спосіб опустити це обмеження - це використовувати похідну таблицю типу:

INSERT INTO dbo.Mytable(ID, Name)
SELECT ID, Name 
FROM (
   VALUES (1, 'a'),
          (2, 'b'),
          --...
          -- more than 1000 rows
)sub (ID, Name);

LiveDemo


Це буде працювати починаючи з SQL Server 2008+


Чи можу я мати посилання на статтю про цей синтаксис "під".
CodeCamper

2
@CodeCamper docs.microsoft.com/en-us/sql/t-sql/queries/… розділ:C. Specifying multiple values as a derived table in a FROM clause
Лукаш Шозда

3
Перевага цієї відповіді полягає в тому, що вона дає спосіб вказати однакові значення, не повторюючи їх (саме це я шукав). Наприклад, з третім стовпцем, який є ідентичним, вам не потрібно було б повторювати це тисячу разів.
Вадим Берман

1
@VadimBerman Так, це хороший сценарій, коли в таблиці не визначено за замовчуванням.
Лукаш Шозда

14

Ви можете це зробити (негарно, але це працює):

INSERT INTO dbo.MyTable (ID, Name) 
select * from
(
 select 123, 'Timmy'
  union all
 select 124, 'Jonny' 
  union all
 select 125, 'Sally'
 ...
) x

10

Це дозволить досягти того, про що ви питаєте:

INSERT INTO table1 (ID, Name)
    VALUES (123, 'Timmy'), 
           (124, 'Jonny'), 
           (125, 'Sally');

Для майбутніх розробників ви також можете вставити з іншої таблиці :

INSERT INTO table1 (ID, Name)
    SELECT 
         ID, 
         Name 
    FROM table2

Або навіть з декількох таблиць :

INSERT INTO table1 (column2, column3)
    SELECT 
         t2.column, 
         t3.column
    FROM table2 t2
         INNER JOIN table3 t3
         ON t2.ID = t3.ID

8

Ви можете використовувати союз:

INSERT INTO dbo.MyTable (ID, Name) 
SELECT ID, Name FROM (
    SELECT 123, 'Timmy'
    UNION ALL
    SELECT 124, 'Jonny'
    UNION ALL
    SELECT 125, 'Sally'
) AS X (ID, Name)

6

Це виглядає нормально для SQL Server 2008. Для SS2005 та новіших версій потрібно повторити оператор VALUES.

INSERT INTO dbo.MyTable (ID, Name)  
VALUES (123, 'Timmy')  
VALUES (124, 'Jonny')   
VALUES (125, 'Sally')  

EDIT :: Моє погано. Ви повинні повторити "ВСТАВИТИ В ІНТО" для кожного ряду в SS2005.

INSERT INTO dbo.MyTable (ID, Name)  
VALUES (123, 'Timmy')  
INSERT INTO dbo.MyTable (ID, Name)  
VALUES (124, 'Jonny')   
INSERT INTO dbo.MyTable (ID, Name)  
VALUES (125, 'Sally')  

6

Простіше використовувати XML в SQL Server, щоб вставити кілька рядків, інакше це стане дуже стомлюючим.

Переглянути повну статтю з поясненнями коду тут http://www.cyberminds.co.uk/blog/articles/how-to-insert-multiple-rows-in-sql-server.aspx

Скопіюйте наступний код на сервер sql, щоб переглянути зразок.

declare @test nvarchar(max)

set @test = '<topic><dialog id="1" answerId="41">
        <comment>comment 1</comment>
        </dialog>
    <dialog id="2" answerId="42" >
    <comment>comment 2</comment>
        </dialog>
    <dialog id="3" answerId="43" >
    <comment>comment 3</comment>
        </dialog>
    </topic>'

declare @testxml xml
set @testxml = cast(@test as xml)
declare @answerTemp Table(dialogid int, answerid int, comment varchar(1000))

insert @answerTemp
SELECT  ParamValues.ID.value('@id','int') ,
ParamValues.ID.value('@answerId','int') ,
ParamValues.ID.value('(comment)[1]','VARCHAR(1000)')
FROM @testxml.nodes('topic/dialog') as ParamValues(ID)

6
USE YourDB
GO
INSERT INTO MyTable (FirstCol, SecondCol)
SELECT 'First' ,1
UNION ALL
SELECT 'Second' ,2
UNION ALL
SELECT 'Third' ,3
UNION ALL
SELECT 'Fourth' ,4
UNION ALL
SELECT 'Fifth' ,5
GO

АЛЕ ВИ МОЖЕТЕ ВИКОРИСТУВАТИ ДРУГИЙ ШЛЯХ

INSERT INTO MyTable (FirstCol, SecondCol)
VALUES 
('First',1),
('Second',2),
('Third',3),
('Fourth',4),
('Fifth',5)

6

Я використовую наступне:

INSERT INTO [TableName] (ID, Name)
values (NEWID(), NEWID())
GO 10

Він додасть десять рядків з унікальними GUID для ідентифікатора та імені.

Примітка: не закінчуйте останній рядок (GO 10) на ';' тому що це призведе до помилки: сталася фатальна помилка сценарію. Під час розбору GO було виявлено неправильний синтаксис.


5

Відповідно до INSERT (Transact-SQL) (SQL Server 2005), ви не можете опускати INSERT INTO dbo.Blahйого і кожного разу вказувати його або використовувати інший синтаксис / підхід,


2

Це працює дуже швидко та ефективно в SQL. Припустимо, у вас є таблиця Sample with 4 column a,b,c,d where a,b,d are int and c column is Varchar(50).

CREATE TABLE [dbo].[Sample](
[a] [int] NULL,
[b] [int] NULL,
[c] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[D] [int] NULL
)

Таким чином, ви не можете вставляти кілька записів у цю таблицю, використовуючи наступний запит, не повторюючи оператор вставки,

DECLARE @LIST VARCHAR(MAX)
SET @LIST='SELECT 1, 1, ''Charan Ghate'',11
     SELECT 2,2, ''Mahesh More'',12
     SELECT 3,3,''Mahesh Nikam'',13
     SELECT 4,4, ''Jay Kadam'',14'
INSERT SAMPLE (a, b, c,d) EXEC(@LIST)

Також із використанням C # SqlBulkCopy bulkcopy = new SqlBulkCopy(con)

Ви можете вставити одночасно 10 рядків

   DataTable dt = new DataTable();
        dt.Columns.Add("a");
        dt.Columns.Add("b");
        dt.Columns.Add("c");
        dt.Columns.Add("d");
        for (int i = 0; i < 10; i++)
        {
            DataRow dr = dt.NewRow();
            dr["a"] = 1;
            dr["b"] = 2;
            dr["c"] = "Charan";
            dr["d"] = 4;
            dt.Rows.Add(dr);
        }
        SqlConnection con = new SqlConnection("Connection String");
        using (SqlBulkCopy bulkcopy = new SqlBulkCopy(con))
        {
            con.Open();
            bulkcopy.DestinationTableName = "Sample";
            bulkcopy.WriteToServer(dt);
            con.Close();
        }

0

Oracle SQL Server Вставте кілька рядків

У багатопозиційну вставку ви вставляєте обчислювані рядки, отримані з рядків, повернених під час оцінки підпиту, в одну або кілька таблиць.

Беззастережна ВСТАВКА ВСІХ : - Щоб додати декілька рядків до таблиці одночасно, ви використовуєте таку форму оператора INSERT:

INSERT ALL
   INTO table_name (column_list) VALUES (value_list_1)
   INTO table_name (column_list) VALUES (value_list_2)
   INTO table_name (column_list) VALUES (value_list_3)
   ...
   INTO table_name (column_list) VALUES (value_list_n)
SELECT 1 FROM DUAL; -- SubQuery

Вкажіть ВСЕ, а потім декілька вставок_інто_клауз, щоб виконати безумовну багатопозиційну вставку. Oracle Database виконує кожну вставку_into_clause один раз для кожного рядка, повернутого підзапитом.

MySQL Server Вставте кілька рядків

INSERT INTO table_name (column_list)
VALUES
    (value_list_1),
    (value_list_2),
    ...
    (value_list_n);

Один рядок Вставити запит

INSERT INTO table_name (col1,col2) VALUES(val1,val2);

0

Інші тут запропонували кілька синтаксисів з декількома записами. Пояснюючи це, я пропоную вам спочатку вставити в таблицю темп, а звідти вставити свою основну таблицю.

Причиною цього є те, що завантаження даних із запиту може зайняти більше часу, і ви можете закінчити блокування таблиці або сторінок довше, ніж це необхідно, що уповільнює інші запити, що працюють проти цієї таблиці.

-- Make a temp table with the needed columns
select top 0 *
into #temp
from MyTable (nolock)

-- load data into it at your leisure (nobody else is waiting for this table or these pages)
insert #temp (ID, Name)
values (123, 'Timmy'),
(124, 'Jonny'),
(125, 'Sally')

-- Now that all the data is in SQL, copy it over to the real table. This runs much faster in most cases.
insert MyTable (ID, Name)
select ID, Name
from #temp

-- cleanup
drop table #temp

Крім того, ваші посвідчення особи, ймовірно, повинні бути ідентичними (1,1), і ви, мабуть, не повинні вставляти їх у переважній більшості обставин. Дозвольте SQL вирішити цей матеріал для вас.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.