Not able to alter column after renaming it - sql

I am first checking if column exist or not. If not then i rename existing column and then try to change its datatype. But when i run script i get error Invalid column name Age
if Not exists(select * from sys.columns
where Name = 'Age' and Object_ID = Object_ID('TestTable'))
begin
EXEC sp_RENAME 'TestTable.Name' , 'Age', 'COLUMN'
ALTER TABLE TestTable ALTER COLUMN Age int
Update TestTable set Age = 0
ALTER TABLE TestTable ALTER COLUMN Age int Not Null
end
What am i doing wrong here?

Try this. By splitting your If condition with Not Exists and exists.
if Not exists(select * from sys.columns
where Name = 'Age' and Object_ID = Object_ID('TestTable'))
BEGIN
EXEC sp_RENAME 'TestTable.Name' , 'Age', 'COLUMN'
END
GO
if exists(select * from sys.columns
where Name = 'Age' and Object_ID = Object_ID('TestTable'))
begin
ALTER TABLE TestTable ALTER COLUMN Age int
Update TestTable set Age = 0
ALTER TABLE TestTable ALTER COLUMN Age int Not Null
END
GO
Edit:
About Batch in SQL from here
A table cannot be changed and then the new columns referenced in the
same batch.
So, renaming and altering in the same batch not worked.
See here
When an error occurs while executing a batch of SQL statements,
No statements in the batch are executed.

Related

SQL:How to create SQL table using some condition [Create table only when condition is true]

Create table tblname if(name='stack').
Create this table only when this condition is true , So how to write this type of query?
I am not an expert...YET!
But you can try the below query with a IF statement In Another If Statment.
It's Difficult to help if we don't know what your end goal is??
DECLARE #Condition Varchar(5) = 'TRUE'
IF(#Condition='True')
BEGIN
IF NOT EXISTS (SELECT object_id FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[Country]') AND type = 'U')
BEGIN
CREATE TABLE [dbo].Country(ID INT, Description Varchar(20))
END
END;
ELSE
BEGIN
PRINT 'IGNORE - DONT CREATE TABLE'
END;

Alter then update causes an error

I have simple script:
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.Columns
WHERE table_name = 'T1' AND column_name = 'C1')
BEGIN
ALTER Table T1
ADD C1 BIT NOT NULL CONSTRAINT DF_T1_C1 DEFAULT 0
UPDATE Table T1
SET C1 = 1
END
GO
I am getting error
Incorrect syntax near the keyword 'Table'.
I tried this solution but it didn't update column value. I came accross this but I think this is not my case as I don't want to catch exceptions or do any transaction. Do I have easy option to do this?
Putting GO seperator didn't help too.
As Joe Taras pointed out, I have changed my script but now getting error
Invalid column name 'C1'.
You need to ensure that that UPDATE isn't compiled until after you're actually created the column.
Put it in a separate context by using EXEC:
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.Columns
WHERE table_name = 'T1' AND column_name = 'C1')
BEGIN
ALTER Table T1
ADD C1 BIT NOT NULL CONSTRAINT DF_T1_C1 DEFAULT 0
EXEC('UPDATE Table T1
SET C1 = 1')
END
GO
Your row:
UPDATE Table T1 SET C1 = 1
has wrong because you have specified table keyword.
The correct syntax is:
UPDATE T1 SET C1 = 1
EDIT 1
Rewrite your script as follow, so after GO separator you'll update your field, so you are sure the DDL has taken by DBMS:
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.Columns
where table_name = 'T1' AND column_name = 'C1')
BEGIN
ALTER Table T1
ADD C1 BIT NOT NULL CONSTRAINT DF_T1_C1 DEFAULT 0
END
GO
UPDATE T1 SET C1 = 1
EDIT 2
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.Columns
where table_name = 'T1' AND column_name = 'C1')
BEGIN
ALTER Table T1
ADD C1 BIT NOT NULL CONSTRAINT DF_T1_C1 DEFAULT 0
EXEC('UPDATE T1 SET C1 = 1')
END
GO
if there is no entry in the table update cannot be done
try it after giving asingle entry it works

Drop indexes or alter

I am trying to drop pk constraint and drop index on the target table in informatica, these below statements are working first time successfully.
IF EXISTS (SELECT Name FROM sysindexes WHERE Name = 'xyz')
DROP INDEX [xyz] ON [dbo].[Table_Name];
IF EXISTS (SELECT Name FROM sysindexes WHERE Name = 'xyz')
ALTER TABLE [dbo].[Table_Name] DROP CONSTRAINT [xyz];
But if I run the same query a second time it is giving an error:
Cannot drop the index 'dbo.Table_Name.xyz', because it does not exist or you do not have permission
I need an If ... Else statement syntax like if exists drop else end or success something.
The likely cause for this is that you might have more than one index named xyz on your database. Your IF EXISTS SELECT statement is not taking into consideration which table xyz is on.
You can check for this condition yourself by running the select statement by itself.
Try changing your query to the following to limit the scope:
If Exists
(
Select *
From sys.indexes
Where name = 'xyz'
And Object_Id = Object_Id('dbo.Table_Name')
)
Drop Index xyz On dbo.Table_Name;
One way to get around this issue is to trick the parser:
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE SCHEMA_NAME = 'dbo' AND TABLE_NAME = 'Table_Name' AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND CONSTRAINT_NAME = 'xyz')
BEGIN
EXEC('ALTER TABLE [dbo].[Table_Name] DROP CONSTRAINT [xyz]')
END

How to add a new column AND insert rows conditionally (in the same script)

I want to add column to a table. If that part of my script executes, I also want to add some values to the table. How can I do it ?
if not exists (select 1 from sys.columns
where object_id = object_id('CAT_MASSUPDATETASKPARAM')
and name = 'ValueBoolean' )
begin
alter table CAT_MASSUPDATETASKPARAM add ValueBoolean bit NULL
end
go
IF (the first script was running do this script )
INSERT INTO CAT_MASSUPDATETASKPARAM ( ParentTaskIK,
ParamType,ParamName,ValueInt,ValueStr,ValueBoolean)
SELECT ParentTaskIK, 'Boolean','SHOW_CURRENT',NULL,NULL,1
FROM CAT_MASSUPDATETASKPARAM ,CAT_MASSUPDATETASK
WHERE CAT_MASSUPDATETASKPARAM.ParentTaskIK = CAT_MASSUPDATETASK.Id
AND CAT_MASSUPDATETASK.MassUpdateType in ('somthing','somthing1')
GROUP BY ParentTaskIK
go
You want the 2nd part to run only if the column was added in the first... Put it in the same begin-end block. But you need dynamic SQL because the column existence is checked at compile time.
if not exists (select 1 from sys.columns where object_id = object_id('CAT_MASSUPDATETASKPARAM') and name = 'ValueBoolean')
begin
alter table CAT_MASSUPDATETASKPARAM add ValueBoolean bit NULL;
EXEC ('
INSERT INTO CAT_MASSUPDATETASKPARAM ( ParentTaskIK, ParamType,ParamName,ValueInt,ValueStr,ValueBoolean)
select ParentTaskIK, ''Boolean'',''SHOW_CURRENT'',NULL,NULL,1
from CAT_MASSUPDATETASKPARAM ,CAT_MASSUPDATETASK
where CAT_MASSUPDATETASKPARAM.ParentTaskIK = CAT_MASSUPDATETASK.Id
and CAT_MASSUPDATETASK.MassUpdateType in (''somthing'',''somthing1'')
group by ParentTaskIK ');
end
go
Otherwise within the same session, you can use a temp table or some such marker:
if not exists (select 1 from sys.columns where object_id = object_id('CAT_MASSUPDATETASKPARAM') and name = 'ValueBoolean')
begin
alter table CAT_MASSUPDATETASKPARAM add ValueBoolean bit NULL;
create table #marker (id int);
end;
GO
if object_id('tempdb..#marker') is not null
INSERT INTO CAT_MASSUPDATETASKPARAM (
ParentTaskIK,ParamType,ParamName,ValueInt,ValueStr,ValueBoolean)
select ParentTaskIK, 'Boolean','SHOW_CURRENT',NULL,NULL,1
from CAT_MASSUPDATETASKPARAM ,CAT_MASSUPDATETASK
where CAT_MASSUPDATETASKPARAM.ParentTaskIK = CAT_MASSUPDATETASK.Id
and CAT_MASSUPDATETASK.MassUpdateType in ('somthing','somthing1')
group by ParentTaskIK;

SQL: How to use a column that was just added

I am trying to add 2 columns and then I would like to set some values to them but I get a compile-error saying the column does not exist. I am using the following script:
IF #LogProcessed = 0
Begin
IF NOT EXISTS (select column_name from INFORMATION_SCHEMA.columns where table_name = 'SYSTM_FRM' and column_name = 'SF_Ip_TXT')
ALTER TABLE SYSTM_FRM add SF_Ip_TXT NVARCHAR(20)
IF NOT EXISTS (select column_name from INFORMATION_SCHEMA.columns where table_name = 'SYSTM_FRM' and column_name = 'SF_Port_NUM')
ALTER TABLE SYSTM_FRM add SF_Port_NUM int
IF (EXISTS (select column_name from INFORMATION_SCHEMA.columns where table_name = 'FRM' and column_name = 'FRM_Ip_TXT') AND
EXISTS (select column_name from INFORMATION_SCHEMA.columns where table_name = 'FRM' and column_name = 'FRM_Ip_TXT'))
begin
Update dbo.SYSTM_FRM
SET dbo.SYSTM_FRM.SF_Ip_TXT = dbo.FRM.FRM_Ip_TXT,
dbo.SYSTM_FRM.SF_Port_NUM = dbo.FRM.FRM_Port_NUM
FROM dbo.FRM INNER JOIN dbo.SYSTM_FRM ON dbo.FRM.FRM_RCRD_NUM = dbo.SYSTM_FRM.SF_FrameRecord_NUM
ALTER TABLE FRM DROP COLUMN FRM_Ip_TXT
ALTER TABLE FRM DROP COLUMN FRM_Port_NUM
end
Update [Update_Log]
Set Update_Log_Processed = 1
Where [Update_Log_Version] = '00001'
end
Is there any way to use a column that I am adding in the same script?
you cannot save it in a proc like that
example
create table TestAdd2 (id int)
go
You cannot create this procedure
create proc prTest as
insert TestAdd2 values (1)
exec ('ALTER TABLE TestAdd2 add SF_Port_NUM int')
update TestAdd2 set id = 1,SF_Port_NUM = 2
select * from TestAdd2
GO
You get this error
Msg 207, Level 16, State 1, Procedure prTest, Line 7
Invalid column name 'SF_Port_NUM'.
This is because at parse time the column does not exist
However if you use dynamic SQL for the update you are good to go
create proc prTest2 as
insert TestAdd2 values (1)
exec ('ALTER TABLE TestAdd2 add SF_Port_NUM int')
exec ('update TestAdd2 set id = 1,SF_Port_NUM = 2')
select * from TestAdd2
GO
in your case your update statement would be
exec('Update dbo.SYSTM_FRM
SET dbo.SYSTM_FRM.SF_Ip_TXT = dbo.FRM.FRM_Ip_TXT,
dbo.SYSTM_FRM.SF_Port_NUM = dbo.FRM.FRM_Port_NUM
FROM dbo.FRM INNER JOIN dbo.SYSTM_FRM
ON dbo.FRM.FRM_RCRD_NUM = dbo.SYSTM_FRM.SF_FrameRecord_NUM')
Put a GO in between
All DDL statements should follow the statement seperator GO in order to make use of it