How to add HIDDEN property on column? - sql-server

When temporal table is created, we need to defined start and end date time columns
which can be hidden - not visible in SELECT * or INSERT without columns. I want to add one more column, which will contain information about the user who has commit the change.
The issue is, I am getting the following error:
Msg 13735, Level 16, State 1, Line 10
Cannot alter HIDDEN attribute on column 'UserID' in table 'GK' because this column is not a generated always column.
Here is the code:
DROP TABLE IF EXISTS GK;
CREATE TABLE GK
(
[ID] INT
,[UserID] BIGINT DEFAULT (CONVERT(BIGINT, SESSION_CONTEXT(N'user_id')))
)
ALTER TABLE GK
ALTER COLUMN [UserID] ADD HIDDEN;
Why I am not allowed to add this attribute on such column?

FOR this you need to use like below
[ GENERATED ALWAYS AS ROW { START | END } [ HIDDEN ] ]
GENERATED ALWAYS AS ROW START/END is compulsory. and
Also note that System-versioned table cannot have more than one 'GENERATED ALWAYS AS ROW END' column
Also note that System-versioned table cannot have more than one 'GENERATED ALWAYS AS ROW START' column
So if you are already using 2 dates column then it will not be possible.
I think we can just use a normal column with default value.
Refer more from Microsoft - https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql

Th correct answer here is that we can add this property only for temporal tables date columns (currently).
If the versioning is stopped and the columns are not hidden, the property is added like this:
ALTER TABLE dbo.Department
ALTER COLUMN SysStartTime ADD HIDDEN;
ALTER TABLE dbo.Department
ALTER COLUMN SysEndTime ADD HIDDEN;

There is a commercial product called DBDefence. It can mask and also completely hide columns in tables for certain logins. It is available for all SQL Servers starting from SQL Server R2.
Disclaimer: I'm associated with the vendor.

Related

DROP all columns from an existing SQL Server table

I need to drop all columns in an existing table in SQL Server. It is possible to delete columns by specifying each column name. I want to delete every column without specifying column name. I am looking for something like
ALTER TABLE tblUser DROP COLUMN *;
Is there any known way to do this?
Answering your question literally, no you can't. If you try to remove the last column, SQL Server will throw the following error:
Msg 4923, Level 16, State 1, Line 12
ALTER TABLE DROP COLUMN failed because 'Id' is the only data column in table 'NoColumns'. A table must have at least one data column.
As such, if you actually want to solve your problem, whatever it is, it would be best to voice the initial problem and not the solution you decided to pursue.
Instead remove all the columns, you could drop the table
DROP TABLE TABLENAME
Or You can mention all the column names in Alter query
ALETR TABLE TableName DROP COLUMN Column1, Column2, Column3....ColumnN

SQL Server 2012: ALTER TABLE ALTER COLUMN MyColumn1 fails because one or more objects access this column

I have a table which contains MyColumn1 with user defined datatype of CustomDatatype INT NOT NULL. I need to change this column to a VARCHAR(5), but I am getting the following errors:
Msg 5074, Level 16, State 1, Line 12
The object 'CustomDatatype' is dependent on column 'MyColumn1'.
Msg 4922, Level 16, State 9, Line 12
ALTER TABLE ALTER COLUMN MyColumn1 failed because one or more objects access this column.
This does not seem to be related to an index or foreign key reference which I would omit to drop before altering the column datatype, this seems to be directly related to the originally used custom defined datatype CustomDatatype on this column.
How can I change MyColumn1's datatype without dropping the CustomDatatype because that could create apocalyptic scenario in my system or dropping the table?
Thanks
Update (2018-07-31): I found a response to the same question in different forum where it states: "...This is the problem with UDT columns. You will need to drop all the columns of this type first in all tables (and may be in functions / SPs, views), then delete the type and create correct type, then re-create all the columns..." (Naomi 2011) from Microsoft (August 2, 2011) web: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/b7bf0f04-dee8-4751-803b-4c3e1f7f7c70/how-to-change-column-nametype-of-user-defined-table-type?forum=transactsql
So far the only viable solutions I came up with are to:
Create a copy of the table (script it out with all
dependencies i.e.: triggers, indexes, keys, etc.) Drop the original
table (which is ok to do even though custom datatypes are specified) and then recreate the table again with the new datatype column.
If the table cannot be dropped (for some reason) rename the old
datatype column, create a new column with the original column name
with the right datatype. Move the data from the old (renamed) column
into the new one (make sure to mind the triggers,etc.). Then force
to recompile all the Sprocs and refresh all the views which are
dependent.
Can you check if there is any Index added for those column?
If yes,
you will need to drop and recreate the index.
once you drop the constraints and index , you can alter the column.
alter table Table1
alter column MyColumn1 varchar(5);
Then re-create constraints and index.
So far the only viable solutions I came up with are to:
1) Create a copy of the table (script it out with all dependencies i.e.: triggers, indexes, keys, etc.) Drop the original table (which is ok to do even though custom datatypes are specified) and then recreate the table again with the new datatype column.
2) If the table cannot be dropped (for some reason) rename the old datatype column, create a new column with the original column name with the right datatype. Move the data from the old (renamed) column into the new one (make sure to mind the triggers,etc.). Then force to recompile all the Sprocs and refresh all the views which are dependent.

SQL Server - How to remove IsPersisted attribute on computed column

In SQL Server, how can we switch off the PERSISTED attribute of a computed column using T-SQL? I am able to do this using Management Studio GUI but do not know how to do it using T-SQL.
If you want to drop the PERSISTED property from your column, then you can try the following:
ALTER TABLE dbo.MyTable ALTER COLUMN MyColumn DROP PERSISTED;
According to MSDN:
[ {ADD | DROP} PERSISTED ]
Specifies that the PERSISTED property is added to or dropped
from the specified column. The column must be a computed column that is
defined with a deterministic expression.
Related: You can also have a look at this article by Aaron Bertrand.
You can do this by following this steps:
Create a new column in your table having the same datatype as that of your persisted column.
Update the new column with the persisted column value.
Remove the persisted column from your table.
Rename the new column as that of the persisted column.

How to remove a column from an existing table?

How to remove a column from an existing table?
I have a table MEN with Fname and Lname
I need to remove the Lname
How to do it?
ALTER TABLE MEN DROP COLUMN Lname
Generic:
ALTER TABLE table_name DROP COLUMN column_name;
In your case:
ALTER TABLE MEN DROP COLUMN Lname;
Your example is simple and doesn’t require any additional table changes but generally speaking this is not so trivial.
If this column is referenced by other tables then you need to figure out what to do with other tables/columns. One option is to remove foreign keys and keep referenced data in other tables.
Another option is to find all referencing columns and remove them as well if they are not needed any longer.
In such cases the real challenge is finding all foreign keys. You can do this by querying system tables or using third party tools such as ApexSQL Search (free) or Red Gate Dependency tracker (premium but more features). There a whole thread on foreign keys here
This is the correct answer:
ALTER TABLE MEN DROP COLUMN Lname
But... if a CONSTRAINT exists on the COLUMN, then you must DROP the CONSTRAINT first, then you will be able to DROP the COLUMN. In order to drop a CONSTRAINT, run:
ALTER TABLE MEN DROP CONSTRAINT {constraint_name_on_column_Lname}
In SQL Server 2016 you can use new DIE statements.
ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name
The above query is re-runnable it drops the column only if it exists in the table else it will not throw error.
Instead of using big IF wrappers to check the existence of column before dropping it you can just run the above DDL statement
The question is, can you only delete a column from an unexisting table ;-)
BEGIN TRANSACTION
IF exists (SELECT * FROM sys.columns c
INNER JOIN sys.objects t ON (c.[object_id] = t.[object_id])
WHERE t.[object_id] = OBJECT_ID(N'[dbo].[MyTable]')
AND c.[name] = 'ColumnName')
BEGIN TRY
ALTER TABLE [dbo].[MyTable] DROP COLUMN ColumnName
END TRY
BEGIN CATCH
print 'FAILED!'
END CATCH
ELSE
BEGIN
SELECT ERROR_NUMBER() AS ErrorNumber;
print 'NO TABLE OR COLUMN FOUND !'
END
COMMIT
The simple answer to this is to use this:
ALTER TABLE MEN DROP COLUMN Lname;
More than one column can be specified like this:
ALTER TABLE MEN DROP COLUMN Lname, secondcol, thirdcol;
From SQL Server 2016 it is also possible to only drop the column only if it exists. This stops you getting an error when the column doesn't exist which is something you probably don't care about.
ALTER TABLE MEN DROP COLUMN IF EXISTS Lname;
There are some prerequisites to dropping columns. The columns dropped can't be:
Used by an Index
Used by CHECK, FOREIGN KEY, UNIQUE, or PRIMARY KEY constraints
Associated with a DEFAULT
Bound to a rule
If any of the above are true you need to drop those associations first.
Also, it should be noted, that dropping a column does not reclaim the space from the hard disk until the table's clustered index is rebuilt. As such it is often a good idea to follow the above with a table rebuild command like this:
ALTER TABLE MEN REBUILD;
Finally as some have said this can be slow and will probably lock the table for the duration. It is possible to create a new table with the desired structure and then rename like this:
SELECT
Fname
-- Note LName the column not wanted is not selected
INTO
new_MEN
FROM
MEN;
EXEC sp_rename 'MEN', 'old_MEN';
EXEC sp_rename 'new_MEN', 'MEN';
DROP TABLE old_MEN;
But be warned there is a window for data loss of inserted rows here between the first select and the last rename command.
To add columns in existing table:
ALTER TABLE table_name
ADD
column_name DATATYPE NULL
To delete columns in existing table:
ALTER TABLE table_name
DROP COLUMN column_name
This can also be done through the SSMS GUI. The nice thing about this method is it warns you if there are any relationships on that column and can also automatically delete those as well.
Put table in Design view (right click on table) like so:
Right click on column in table's Design view and click "Delete
Column"
As I stated before, if there are any relationships that would also need to be deleted, it will ask you at this point if you would like to delete those as well. You will likely need to do so to delete the column.
If you are using C# and the Identity column is int, create a new instance of int without providing any value to it.It worked for me.
[identity_column] = new int()
Syntax:
ALTER TABLE TABLE_NAME DROP COLUMN COLUMN_NAME;
For Example:
alter table Employee drop column address;

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.

Resources