Оператор вставки SQL с выбором - PullRequest
1 голос
/ 12 февраля 2009

У меня есть следующий оператор SQL

INSERT INTO A_Table (field1, field2) 
  SELECT field1, field2 FROM B_Table
  WHERE field1 NOT IN (
    SELECT field1 FROM A_Table);

В основном мне нужно скопировать все данные из B_Table в A_Table с ограничением: field1 из B_Table, которого нет в A_Table. Мне нужно добавить это ограничение, так как field1 является ключом.

Это похоже на конфликт: field1 не в A_Table копируется из B_Table в A_Table. В процессе вставки скопированная запись из B_Table будет существовать в A_Table. Не уверен, работает ли он или нет, или какой-либо неожиданный результат?

Может быть, все в порядке. Последний SELECT кэшируется во временной таблице и не обновляется при вставке?

Кстати, мой SQL-сервер - это Microsoft SQL Server 2005.

Ответы [ 6 ]

4 голосов
/ 12 февраля 2009

возможно, это поможет, если вы посмотрите на свой запрос как на два отдельных оператора

оператор выбора

  SELECT field1, field2 FROM B_Table
  WHERE field1 NOT IN (
    SELECT field1 FROM A_Table)

, который дает вам некоторые результаты

теперь вы вставляете эти результаты в таблицу A_table

INSERT INTO A_Table (field1, field2)

и код для этого

INSERT INTO A_Table (field1, field2)
  SELECT field1, field2 FROM B_Table
  WHERE field1 NOT IN (
    SELECT field1 FROM A_Table)

это то, что вы в основном опубликовали

1 голос
/ 12 февраля 2009

ваш оператор вставки будет работать, как продемонстрировано этим SQL -

CREATE TABLE #temp1 (id INT IDENTITY(1,1) PRIMARY KEY CLUSTERED , [name] NVARCHAR(20))
CREATE TABLE #temp2 (id INT IDENTITY(1,1) PRIMARY KEY CLUSTERED , [name] NVARCHAR(20))

INSERT INTO #temp1 ([name])
VALUES ('name1')
INSERT INTO #temp1 ([name])
VALUES ('name2')
INSERT INTO #temp1 ([name])
VALUES ('name3')
INSERT INTO #temp1 ([name])
VALUES ('name4')
INSERT INTO #temp2 ([name])
VALUES ('Othername1')
INSERT INTO #temp2 ([name])
VALUES ('Othername2')

INSERT INTO #temp2 (name)
SELECT name FROM #temp1
WHERE id NOT IN (SELECT id FROM #temp2)

SELECT * FROM #temp1
SELECT * FROM #temp2

DROP TABLE #temp1
DROP TABLE #temp2

результаты в

temp1

ИД

1 имя1
2 name2
3 name3
4 name4

temp2

ИД

1 Othername1
2 Othername2
3 name3
4 name4

1 голос
/ 12 февраля 2009

Результирующий набор SELECT определяется перед любой вставкой, поэтому конфликта нет. В противном случае такие заявления никогда не будут безопасными. Это немного похоже на код:

x = 1;
x = x + x + 1;

Правая часть вычисляется, и только затем присваивается переменной слева - в противном случае, кто знает, как закончится x!

1 голос
/ 12 февраля 2009

SQL-операторы выполняются так, как будто все происходит мгновенно. Нет никакого момента во времени, когда (логически говоря) инструкция была частично выполнена.

0 голосов
/ 12 февраля 2009

Должно работать нормально.

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

0 голосов
/ 12 февраля 2009

Похоже, что этот запрос не будет работать в его текущей форме, потому что вы не указываете столбец в своем подзапросе. Скорее всего, он все еще выполняется и предполагает, что вы имеете в виду not in (null)

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