Как обновить одну таблицу из другой без указания имен столбцов?

У меня есть две таблицы с одинаковой структурой и ОЧЕНЬ БОЛЬШИМ количеством полей (около 1000). Мне нужно выполнить 2 операции 1) Вставить из второй таблицы все строки в первую. Пример:

INSERT INTO [1607348182]
SELECT * 
FROM _tmp_1607348182;

2) Обновите первую таблицу из второй таблицы, но для обновления я не могу найти правильный синтаксис sql для обновления.

Такие запросы:

Update [1607348182]
set [1607348182].* = tmp.*
from [1607348182]
inner join _tmp_1607348182 as tmp on tmp.recordid = [1607348182].recordid

or

Update [1607348182]
from [1607348182]
inner join _tmp_1607348182 as tmp on tmp.recordid = [1607348182].recordid

недействительны.


person amuliar    schedule 08.10.2010    source источник
comment
Я бы рекомендовал использовать TRIGGER или изменить схему, чтобы вам не приходилось этого делать.   -  person Travis Gockel    schedule 08.10.2010
comment
Я не понимаю. После вашего первого обновления две таблицы будут содержать одинаковые строки, так что же вы надеетесь сделать при втором обновлении?   -  person PaulG    schedule 08.10.2010
comment
Трэвис Г., я согласен с вами изменить схему базы данных, но, к сожалению, я должен следовать этой схеме в своем проекте.   -  person amuliar    schedule 08.10.2010
comment
PaulG: я описал два возможных типа операций, которые мне нужны   -  person amuliar    schedule 08.10.2010


Ответы (2)


Не уверен, что вы сможете сделать это без использования динамического sql для построения оператора обновления в переменной.

Этот оператор вернет список столбцов на основе введенного вами имени таблицы:

select name from syscolumns
where [id] = (select [id] from sysobjects where name = 'tablename')

Не уверен, смогу ли я избежать здесь цикла... вам нужно будет загрузить результаты сверху в курсор, а затем построить из него запрос. Псевдо закодировано:

set @query = 'update [1607348182] set '
load cursor --(we will use @name to hold the column name)
while stillrecordsincursor
set @query = @query + @name + ' = tmp_[1607348182]. ' +@name + ','
load next value from cursor
loop!

Когда запрос будет построен в цикле, используйте exec sp_executesql @query.

Небольшое предупреждение... построение динамического sql в таком цикле может немного запутать. Для устранения неполадок поместите select @query в цикл и посмотрите, как @query будет построен.

редактировать: не уверен, что вы сможете сделать все 1000 строк в обновлении одновременно... есть логические ограничения (varchar (8000)?) на размер, который @query также может расти. Возможно, вам придется разделить код, чтобы он обрабатывал 50 столбцов за раз. Поместите столбцы из оператора select syscolumns во временную таблицу с идентификатором и создайте свой динамический sql, чтобы он обновлял 20 столбцов (или 50?) за раз.

Другой альтернативой может быть использование Excel для массового создания этого. Выберите столбец и скопируйте результаты в столбец a электронной таблицы. Поместите '= в столбец b, tmp.[12331312] в столбце c скопируйте столбец a в столбец D и запятую в столбец e. Скопируйте всю электронную таблицу в блокнот, и у вас должны быть построены столбцы оператора обновления. Неплохое решение, если это одноразовое событие, не уверен, что я буду полагаться на это как на постоянное решение.

person Twelfth    schedule 08.10.2010
comment
Кажется, это лучшее решение, потому что в sql нет собственного выражения для этого. Также у меня были проблемы с другими ограничениями SQL Server, связанными со столбцами переменного размера. (Также я понимаю, что мои проблемы возникают из-за плохой схемы БД). Таким образом, ваше решение кажется лучшим, потому что я могу кэшировать этот оператор SQL и повторно использовать его позже в других запросах. - person amuliar; 15.10.2010
comment
Об ограничении varchar(8000). Я все равно могу создать varchar(MAX) - person amuliar; 15.10.2010
comment
Хорошо, я недавно работал с устаревшими базами данных и забыл о varchar (max). Что касается плохой схемы БД... Я предполагаю, что вы работаете со старой схемой (редко видите таблицы с именами за пределами плоских файлов/IDBMS). Ночной импорт из устаревшей системы в нормализованную базу данных может быть хорошим вариантом для рассмотрения, иначе вы столкнетесь с относительно большим количеством времени, затрачиваемым на работу с этой плохой схемой, которая будет добавляться к каждому проекту, который вы делаете. - person Twelfth; 15.10.2010

Будет ли работать удаление всего из мастер-таблицы с временным идентификатором, а затем выполнение вставки с новыми данными?

person Kendrick    schedule 08.10.2010
comment
Да, я понял это решение и реализовал его. Спасибо - person amuliar; 15.10.2010