Column not found - sql-server

I tried below in sql server management, in a single query.
alter table add column amount2
update table set amount2=amount
I am getting column amount2 not found.
Can anyone tell me why this error?

That is not valid syntax (misses table name and column datatype) but in management studio use the batch separator GO between adding a column to an existing table and statements referencing the new column anyway.
Or alternatively you can use EXEC to execute it in a child batch.
SQL Server tries to compile all statements in the batch before execution and this will fail when it encounters the statement using this column.

There's a couple things wrong here.
The correct syntax for adding a column is MSDN - ALTER TABLE
ALTER TABLE [TableName] ADD [ColumnNAME] [DataType]
'Table' is a Reserved Keyword in SQL Server, although it is possible to have a table named 'Table'. You need to include brackets when referencing it.
SELECT * FROM [Table]
All together, you need
ALTER TABLE [Table] ADD [Amount2] INT
GO -- See Martin's answer for reason why 'GO' is needed here
UPDATE [Table] SET [Amount2] = [Amount]

You can get around this problem like this:
-- Alter the table and add new column "NewColumn"
ALTER TABLE [MyTable] ADD [NewColumn] CHAR(1) NULL;
-- Set the value of NewColumn
EXEC ('UPDATE [MyTable] SET [NewColumn] = ''A'' ');

Related

Running an alter table alter column statement more than once in SQL Server

Are there any negative implications to running an alter table alter column statement more than once in SQL Server?
Say I alter a column's datatype and nullability like this:
--create table
create table Table1
(
Column1 varchar(50) not null
)
go
--insert some records
insert into Table1 values('a')
insert into Table1 values('b')
go
--alter once
alter table Table1
alter column Column1 nvarchar(250) not null
go
--alter twice
alter table Table1
alter column Column1 nvarchar(250) not null
go
The above set of sql all works and I have tested these. I could also test for the properties in the alter statements. The question is that is there any advantage to say checking if the column is not already nullable before altering.
After the first alter, does SQL Server figure out that the table has already been altered and hence the 2nd alter essentially does nothing?
Are there any differences across different versions of SQL Server about how this is handled?
Thanks,
Ilias
This is a metadata only operation.
It doesn't have to read or write any of the data pages belonging to Table1. It isn't quite a no-op though.
It will still start up a transaction, acquire a schema modification lock on the table and update the modified column in the row for this table in sys.sysschobjs (exposed to us through the modified_date column in sys.objects).
Moreover because the table has been modified any execution plans referencing the table will need to be recompiled on next usage.

How to Alter Column from nvarchar(max) to nvarchar(50)

I have an existing table in SQL SERVER 2008 with one of its column as NVARCHAR(MAX) and it only has values of less than 10 characters in it.
This table is in production and has data in it.
I have got a requirement wherein I have to Alter this column from NVARCHAR(MAX) to NVARCHAR(50). The SQL Server gives some Truncation error while doing this operation, even though the data in that column is less than 10 characters.
This is my script:
ALTER TABLE [dbo].[Table] ALTER COLUMN [Column1] NVARCHAR ( 50 ) NOT NULL
First Check Your table data with this query:
SELECT DATALENGTH(Column_Name) AS FIELDSIZE, Column_Name
FROM Table_Name
If everything is fine, you may have checked the Prevent Saving Changes option. Follow these steps to check:
Tools > Designers Uncheck Prevent saving changes that require table re-creation
If you are sure that you wouldn't lose data, then:
Update myTable set myNVMaxCol = left(coalesce(myNVMaxCol,''),50);
Alter table myTable alter column myNVMaxCol nvarchar(50) not null;

Test Column exists, Add Column, and Update Column

I'm trying to write a SQL Server database update script. I want to test for the existence of a column in a table, then if it doesn't exist add the column with a default value, and finally update that column based on the current value of a different column in the same table. I want this script to be runnable multiple times, the first time updating the table and on subsequent runs the script should be ignored. My script currently looks like the following:
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'PurchaseOrder' AND COLUMN_NAME = 'IsDownloadable')
BEGIN
ALTER TABLE [dbo].[PurchaseOrder] ADD [IsDownloadable] bit NOT NULL DEFAULT 0
UPDATE [dbo].[PurchaseOrder] SET [IsDownloadable] = 1 WHERE [Ref] IS NOT NULL
END
SQL Server returns error "Invalid column name 'IsDownloadable'", i.e. I need to commit the DDL before I can update the column. I've tried various permutations but I'm getting nowhere fast.
This script will not run successfully unless the column already exists, which is exactly when you don't need it.
SQL Scripts have to be parsed before they can be executed. If the column doesn't exist at the time the script is parsed, then the parsing will fail. It doesn't matter that your scripts creates the column later on; the parser has no way of knowing that.
You need to put in a GO statement (batch separator) if you want to access a column that you just added. However, once you do that, you can no longer maintain any control flow or variables from the previous batch - it's like running two separate scripts. This makes it tricky to do both DDL and DML, conditionally, at the same time.
The simplest workaround, which I'd probably recommend for you because your DML is not very complex, is to use dynamic SQL, which the parser won't try to parse until "runtime":
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'PurchaseOrder' AND COLUMN_NAME = 'IsDownloadable')
BEGIN
ALTER TABLE [dbo].[PurchaseOrder] ADD
[IsDownloadable] bit NOT NULL DEFAULT 0
EXEC sp_executesql
N'UPDATE [dbo].[PurchaseOrder] SET [IsDownloadable] = 1 WHERE [Ref] IS NOT NULL'
END
I have often been annoyed by this problem myself, and unfortunately the solution suggested in Aaronaught's answer quickly becomes messy when #parameters and 'strings' are involved. However, I have found a different workaround by exploiting the usage of synonyms:
IF(COL_LENGTH('MyTable', 'NewCol') IS NULL)
BEGIN
ALTER TABLE MyTable ADD NewCol VARCHAR(16) NULL;
CREATE SYNONYM hack FOR MyTable;
UPDATE hack SET NewCol = 'Hello ' + OldCol;
DROP SYNONYM hack;
ALTER TABLE MyTable ALTER COLUMN NewCol VARCHAR(16) NOT NULL;
END
Try adding a "GO" statement after the ALTER TABLE.
It was news to me, but it says here that all statements in a batch (those preceeding the GO) are compiled into one query plan.) Withou no GO in the SQL, the entire plan is effectively one query.
EDIT: Since GO gives a syntax error (which seemed strange to me), I created something similar, and found this worked
declare #doUpdate bit;
SELECT #doUpdate = 0;
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'PurchaseOrder' AND COLUMN_NAME = 'IsDownloadable')
BEGIN
SELECT #doUpdate=1
END
IF #doUpdate<>0
ALTER TABLE [dbo].[PurchaseOrder] ADD [IsDownloadable] bit NOT NULL DEFAULT 0
IF #doUpdate<>0
UPDATE [dbo].[PurchaseOrder] SET [IsDownloadable] = 1 WHERE [Ref]=0
COMMIT TRAN
Although the accepted answer does work, for a more complicated case, you can use a temp table to persist data past the GO statement. just make sure you remember to clean it up after.
For example:
-- Create a tempTable if it doesn't exist. Use a unique name here
IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL DROP TABLE #tempTable
CREATE TABLE #tempTable (ColumnsCreated bit)
-- Create your new column if it doesn't exist. Also, insert into the tempTable.
IF NOT EXISTS (
SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'targetTable' AND COLUMN_NAME = 'newColumn')
BEGIN
INSERT INTO #tempTable VALUES (1)
ALTER TABLE .dbo.targetTable ADD newColumn [SMALLINT] NULL ;
END
GO
-- If the tempTable was inserted into, our new columns were created.
IF (EXISTS(SELECT * FROM #tempTable))
BEGIN
-- Do some data seeding or whatever
END
-- Clean up - delete the tempTable.
IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL DROP TABLE #tempTable
If you're using at least SQL Server 2008, you can specify WITH VALUES at the time of column addition, which will populate existing records with the default value for that attribute.
IF COL_LENGTH('[dbo].[Trucks]', 'Is4WheelDrive') IS NULL
BEGIN
ALTER TABLE [dbo].[Trucks]
ADD [Is4WheelDrive] BIT NULL DEFAULT 1
WITH VALUES;
END
This will add a new column, [Is4WheelDrive], to the table [dbo].[Trucks] if that column doesn't exist. The new column, if added, will populate existing records with the default value, which in this case is a BIT value of 1. If the column already existed, no records would be modified.

Altering a column: null to not null

I have a table that has several nullable integer columns. This is undesirable for several reasons, so I am looking to update all nulls to 0 and then set these columns to NOT NULL. Aside from changing nulls to 0, data must be preserved.
I am looking for the specific SQL syntax to alter a column (call it ColumnA) to "not null". Assume the data has been updated to not contain nulls.
Using SQL server 2000.
First, make all current NULL values disappear:
UPDATE [Table] SET [Column]=0 WHERE [Column] IS NULL
Then, update the table definition to disallow "NULLs":
ALTER TABLE [Table] ALTER COLUMN [Column] INTEGER NOT NULL
I had the same problem, but the field used to default to null, and now I want to default it to 0. That required adding one more line after mdb's solution:
ALTER TABLE [Table] ADD CONSTRAINT [Constraint] DEFAULT 0 FOR [Column];
You will have to do it in two steps:
Update the table so that there are no nulls in the column.
UPDATE MyTable SET MyNullableColumn = 0
WHERE MyNullableColumn IS NULL
Alter the table to change the property of the column
ALTER TABLE MyTable
ALTER COLUMN MyNullableColumn MyNullableColumnDatatype NOT NULL
For Oracle 11g, I was able to change the column attribute as follows:
ALTER TABLE tablename MODIFY columnname datatype NOT NULL;
Otherwise abatichev's answer seemed good. You can't repeat the alter - it complains (at least in SQL Developer) that the column is already not null.
this worked for me:
ALTER TABLE [Table]
Alter COLUMN [Column] VARCHAR(50) not null;
As long as the column is not a unique identifier
UPDATE table set columnName = 0 where columnName is null
Then
Alter the table and set the field to non null and specify a default value of 0
In case of FOREIGN KEY CONSTRAINT... there will be a problem if '0' is not present in the column of Primary key table. The solution for that is...
STEP1:
Disable all the constraints using this code :
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
STEP2:
RUN UPDATE COMMAND (as mentioned in above comments)
RUN ALTER COMMAND (as mentioned in above comments)
STEP3:
Enable all the constraints using this code :
exec sp_msforeachtable #command1="print '?'", #command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
this seems simpler, but only works on Oracle:
ALTER TABLE [Table]
ALTER [Column] NUMBER DEFAULT 0 NOT NULL;
in addition, with this, you can also add columns, not just alter it.
It updates to the default value (0) in this example, if the value was null.
In my case I had difficulties with the posted answers. I ended up using the following:
ALTER TABLE table_name CHANGE COLUMN column_name column_name VARCHAR(200) NOT NULL DEFAULT '';
Change VARCHAR(200) to your datatype, and optionally change the default value.
If you don't have a default value you're going to have a problem making this change, as default would be null creating a conflict.
Making column not null and adding default can also be done in the SSMS GUI.
As others have already stated, you can't set "not null" until all
the existing data is "not null" like so:
UPDATE myTable SET myColumn = 0
Once that's done, with the table in design view (right click on
table and click "design view"), you can just uncheck the Allow
Nulls columns like so:
Still in design view with the column selected, you can see the
Column Properties in the window below and set the default to 0 in there as well like so:
Let's take an example:
TABLE NAME=EMPLOYEE
And I want to change the column EMPLOYEE_NAME to NOT NULL. This query can be used for the task:
ALTER TABLE EMPLOYEE MODIFY EMPLOYEE.EMPLOYEE_NAME datatype NOT NULL;
For the inbuilt javaDB included in the JDK (Oracle's supported distribution of the Apache Derby) the below worked for me
alter table [table name] alter column [column name] not null;
You can change the definition of existing DB column using following sql.
ALTER TABLE mytable modify mycolumn datatype NOT NULL;
First make sure the column that your changing to not does not have null values
select count(*) from table where column's_name is null
Impute the missing values. you can replace the nulls with empty string or 0 or an average or median value or an interpolated value. It depends on your back fill strategy or forward fill strategy.
Decide if the column values need to be unique or non-unique. if they need to be unique than add an unique constraint. Otherwise, see if performance is adequate or if you need to add an index.

How to change the data type of a column without dropping the column with query?

I have a column which has a datatype : datetime. But now i want to convert it to datatype varchar. Can i alter the datatype without droppping the column? If yes, then please explain how?
MSDN says
ALTER TABLE mytable ALTER COLUMN mycolumn newtype
Beware of the limitations of the ALTER COLUMN clause listed in the article
If ALTER COLUMN doesn't work.
It is not unusual for alter column to fail because it cannot make the transformation you desire. In this case, the solution is to create a dummy table TableName_tmp, copy the data over with your specialized transformation in the bulk Insert command, drop the original table, and rename the tmp table to the original table's name. You'll have to drop and recreate the Foreign key constraints and, for performance, you'll probably want to create keys after filling the tmp table.
Sound like a lot of work? Actually, it isn't.
If you are using SQL Server, you can make the SQL Server Management Studio do the work for you!
Bring up your table structure (right-click on the table column and select "Modify")
Make all of your changes (if the column transformation is illegal, just add your new column - you'll patch it up in a moment).
Right-click on the background of the Modify window and select "Generate Change Script." In the window that appears, you can copy the change script to the clipboard.
Cancel the Modify (you'll want to test your script, after all) and then paste the script into a new query window.
Modify as necessary (e.g. add your transformation while removing the field from the tmp table declaration) and you now have the script necessary to make your transformation.
ALTER TABLE [table name] MODIFY COLUMN [column name] datatype
ALTER TABLE YourTableNameHere ALTER COLUMN YourColumnNameHere VARCHAR(20)
Type the below query:
alter table table_Name alter column column_name datatype
e.g.
alter table Message alter column message nvarchar(1024);
ALTER TABLE YourTableNameHere ALTER COLUMN YourColumnNameHere VARCHAR(20)
With SQL server 2008 and more, using this query:
ALTER TABLE [RecipeInventorys] ALTER COLUMN [RecipeName] varchar(550)
This work for postgresql 9.0.3
alter table [table name] ALTER COLUMN [column name] TYPE [character varying];
http://www.postgresql.org/docs/8.0/static/sql-altertable.html
ALTER TABLE [table_name] ALTER COLUMN [column_name] varchar(150)
ALTER TABLE YourTableNameHere ALTER COLUMN YourColumnNameHere VARCHAR(20) this is perfect for change to datatype
ORACLE - Alter table table_name modify(column_name new_DataType);
ALTER TABLE yourtable MODIFY COLUMN yourcolumn datatype
ALTER TABLE table_name
MODIFY (column_name data_type);
ALTER tablename MODIFY columnName newColumnType
I'm not sure how it will handle the change from datetime to varchar though, so you may need to rename the column, add a new one with the old name and the correct data type (varchar) and then write an update query to populate the new column from the old.
http://www.1keydata.com/sql/sql-alter-table.html
alter table [table name] remove [present column name] to [new column name.

Resources