SQL скрипт, операторы if и go - PullRequest
0 голосов
/ 19 марта 2012

Мне нужно окружить следующий скрипт sql if-проверкой, которая проверяет существование одной таблицы.В операторе гораздо больше полей, но приведенного ниже фрагмента должно быть достаточно, чтобы понять идею.

Если я окружу весь этот пакет утверждением if, мне не понравится, что у меня есть GO между статами if.Если я уберу GO, он будет жаловаться на то, что TMP_FIELD является недопустимым столбцом.

Как можно сделать это правильно?Все, что я делаю, это собираю кучу полей и перехожу с varchar на datetime.Это часть файла setup.exe, поэтому мне нужно запустить его один раз, а не для будущих обновлений.Как я определяю, если определенная таблица существует, не запускайте сценарий.

IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'MY_TABLE') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
  ALTER TABLE MY_TABLE ADD TMP_FIELD datetime
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'MY_TABLE') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
  UPDATE MY_TABLE SET TMP_FIELD = modifiedDate
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'MY_TABLE') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
  ALTER TABLE MY_TABLE DROP COLUMN modifiedDate
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'MY_TABLE') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
  ALTER TABLE MY_TABLE ADD modifiedDate datetime
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'MY_TABLE') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
  UPDATE MY_TABLE SET modifiedDate = TMP_FIELD
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'MY_TABLE') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
  ALTER TABLE MY_TABLE DROP COLUMN TMP_FIELD
GO

Ответы [ 3 ]

1 голос
/ 19 марта 2012

Вам не нужно делать всю эту гимнастику для изменения типа столбца, не так ли?

create table MY_TABLE (
    modifiedDate varchar(20)
)
go

insert MY_TABLE (modifiedDate) values ('2012-10-20 17:50:41')
go

select * from MY_TABLE
go

alter table MY_TABLE alter column modifiedDate datetime
go

select * from MY_TABLE
go

drop table MY_TABLE
go

Итак, я бы написал ваше утверждение так:

if exists (select table_name from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'MY_TABLE')
begin
  alter table MY_TABLE alter column modifiedDate datetime
end
0 голосов
/ 20 марта 2012

Если вы хотите обойти ошибки 'Invalid column ..', один из вариантов - использовать динамический SQL. например :

create table dbo.t1 (id int primary key, cola varchar(20))
go

insert dbo.t1 values (1, 'one')
insert dbo.t1 values (2, 'two')   
go

if not exists(select  * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 't1' and COLUMN_NAME = 'colb')
BEGIN
    -- add new column 'colb', and set its value initially to existing values in 'cola' 
    ALTER TABLE dbo.t1 ADD colb varchar(20)

    DECLARE @v NVARCHAR(500)
    SET @v = N'UPDATE dbo.t1 SET colb = cola'
    EXEC (@v) -- use dynamic SQL, otherwise will get Invalid column name colb error.    
END
GO

Обратите внимание, что динамический SQL следует рассматривать как последнее средство. Ответ Дэвида Брабанта, кажется, является способом решения вашей первоначальной проблемы.

0 голосов
/ 19 марта 2012

GO отмечают конец пакета операторов TSQL.Нельзя смешивать операторы DDL (язык определения данных), такие как ALTER TABLE, с операторами DML (язык манипулирования данными), такими как UPDATE TABLE, в одном пакете.

Каждый пакет компилируется самостоятельно.Поэтому, когда операторы ALTER TABLE и UPDATE TABLE находятся в одном пакете, SQL Server не может скомпилировать оператор обновления, поскольку столбецifiedData еще не был создан.

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