Модераторы: Akina
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Объединение таблиц, Выходит ошибка при перечислении полей 
:(
    Опции темы
SoulB
Дата 10.9.2009, 23:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 4.9.2009

Репутация: нет
Всего: нет



Имеются 2 таблицы Persons и Users. Нужно переместить данные из столбцов [FirstName], [LastName], [Gender], [CountryId], [CityId] int,  [isNotifiedByEmail] таблицы Persons в таблицу Users (в Users нужно создать такие столбцы). Как я делаю:
Создаю табличную переменную, засовываю туда данные, которые нужно переместить (+колонка с identity для индексации). Делаю ALTER TABLE Users ADD <нужные столбцы>. В цикле загоняю из временной таблицы в новые столбцы. Затем уже создаю форейн кейсы.

В чем проблема:
Дело в том что компилироваться не хочет. Если столбцы еще не созданы, а в коде в начале есть добавление в таблицу новых столбцов, то компилятор все равно сообщает, что таких полей нет. Если в начале отдельно создать поля, а затем запустить код с добавлением, то работает отлично. Как решить проблему7 Нужно все сделать в одном запросе в виде скрипта для апдейта базы, без использования и создания stored procedures. 
Подключаю код, то что нахимичил:

Код

begin transaction
--Adding data from Persons table to @table
declare @table table(
     ind int identity(1,1), UserId int, 
     FirstName nvarchar(50), LastName nvarchar(50),
     Gender bit, CountryId int, CityId int, isNotifiedByEmail bit);
insert into @table
  select UserId, FirstName, LastName, 
         Gender, CountryId, CityId, isNotifiedByEmail
  from Persons;

--Adding new columns to Users table
alter table [dbo].[Users]
add [FirstName] nvarchar(50) COLLATE Cyrillic_General_CI_AS NULL,
    [LastName] nvarchar(50) COLLATE Cyrillic_General_CI_AS NULL,
    [Gender] bit NOT NULL DEFAULT ((0)),
    [CountryId] int NOT NULL DEFAULT ((0)),
    [CityId] int NOT NULL DEFAULT ((0)),
    [isNotifiedByEmail] bit NULL DEFAULT ((1));

--Adding data to altered Users table from @table
--Cycle working by cycle
declare @from int, @to int, @userId int
declare @alterTable nvarchar(max);
declare @FirstName nvarchar(50),
        @LastName nvarchar(50),
        @Gender bit,
        @CountryId int,
        @CityId int,
        @isNotifiedByEmail bit;
set @to = (select COUNT(*) from @table);
set @from=1;
declare @command nvarchar(max)

while (@from<=@to)
  begin
   set @UserId=(select UserId from @table as t where t.ind=@from)
   set @FirstName=(select FirstName from @table as t where t.ind=@from)
   set @LastName=(select LastName from @table as t where t.ind=@from)
   set @Gender=(select Gender from @table as t where t.ind=@from)
   set @CountryId=(select CountryId from @table as t where t.ind=@from)
   set @CityId=(select CityId from @table as t where t.ind=@from)
   set @isNotifiedByEmail=(select isNotifiedByEmail from @table as t where t.ind=@from)
   
--Здесь возникает ошибка! Говорит, что таких столбцов не существует. Пробовал через sp_executesql передать строку - все равно.
   update [dbo].[Users]
    set FirstName=@FirstName,
        LastName=@LastName,
        Gender=@Gender,
        CountryId=@CountryId,
        CityId=@CityId,
        isNotifiedByEmail=@isNotifiedByEmail
    where @UserId=Users.UserId
  set @from=@from+1;
end   
 
--Adding foreign keys to new columns
alter table [dbo].[Users] with check add constraint [FK_Users_Cities] foreign key([CityId])
references [dbo].[Cities] ([CityId])
alter table [dbo].[Users] check constraint [FK_Users_Cities]

alter table [dbo].[Users]  with check add constraint [FK_Users_Countries] foreign key([CountryId])
references [dbo].[Countries] ([CountryId])
alter table [dbo].[Users] check constraint [FK_Users_Countries]

--deleting constraints and columns from Persons table
alter table [dbo].[Persons] drop constraint [FK_Persons_Cities]
alter table [dbo].[Persons] drop constraint [FK_Persons_Countries]
alter table [dbo].[Persons]
drop column FirstName, LastName, Gender, CountryId, CityId, isNotifiedByEmail

if @@trancount>0 commit transaction
else
rollback

--Checking =)
select * from Users


PM MAIL WWW   Вверх
Zioma
Дата 11.9.2009, 08:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 22.8.2007

Репутация: 5
Всего: 5



В 2008-м такая конструкция отрабатывает.
Под рукой нет 2000-ого и 2005-ого, но по-моему там такое решалось именно с помощью sp_executesql.
PM MAIL   Вверх
SoulB
  Дата 11.9.2009, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 4.9.2009

Репутация: нет
Всего: нет



Все решилось. Оказывается после каждого использования ALTER TABLE следует ставить GO. Как я понял - это отделяет блок как отдельный пакет, что мне и нужно было  smile.  Вроде легкое задание, а убил на это целый день, да еще и почти всю ночь думал. Спасибо за отзыв
PM MAIL WWW   Вверх
Akina
Дата 11.9.2009, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 25
Всего: 454



Цитата(SoulB @  11.9.2009,  10:02 Найти цитируемый пост)
Оказывается после каждого использования ALTER TABLE следует ставить GO.

Ну в общем очевидно. Во-первых, во всех примерах в MSDN именно так. Во-вторых, попробуй думать как сервер: юзер сказал поменять это, юзер сказал поменять то... блин, а "то" менять в том, что получится, если поменять "это", или нет? а вот хрен его знает... 


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
SoulB
Дата 11.9.2009, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 4.9.2009

Репутация: нет
Всего: нет



 smile ок, теперь другая проблема. Все работает, отлично, добавляет, удаляет, обновляет. Заканчивает транзакцию, показывает, что операция выполнена, но теперь я не могу через Management Studio открыть таблицу, только через запросы. При попытке Take Offline базы - виснет, затем выдает ошибку, что база не доступна. Делаю Drop Connecion базы - вижу, что сидит какое-то подключение с PID процесса 52 в состоянии sleeping. Kill process - и база сразу доступна и оффлайнится спокойно. Что за ерунда? Пробовал без включения транзакции - результат тот же.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "MS SQL"
Akina

Akina

Запрещается!

Публиковать ссылки и обсуждать взлом чего бы то ни было.

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы составления неспецифических запросов рассматриваются здесь
  • Используйте теги [code=sql][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, Akina.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MS SQL Server | Следующая тема »


 




[ Время генерации скрипта: 0.0984 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.