SQL Server: Add a column with calculated Field - sql

I'm trying to alter a table to add an additional column that has the last 3 digits of org_id. I am doing this because software I am using cannot read 34000000000000000002 because of the size. I would like to turn 34000000000000000002 into 002 and put it in the new column. I thought something like below would work
alter table [org] add new_org_id integer value (select right(org_id,3));
I am very new at sql so I apologize if i'm not even close.

You were close. See the documentation for the correct syntax.
alter table [org] add new_org_id as right(org_id,3);
Also, you may want to make this a persisted computed column
PERSISTED Specifies that the Database Engine will physically store the
computed values in the table, and update the values when any other
columns on which the computed column depends are updated. Marking a
computed column as PERSISTED allows an index to be created on a
computed column that is deterministic, but not precise. For more
information, see Indexes on Computed Columns. Any computed columns
used as partitioning columns of a partitioned table must be explicitly
marked PERSISTED. computed_column_expression must be deterministic
when PERSISTED is specified.

Pretty close I think.
I'd do
alter table [org] add new_org_id integer
UPDATE [org]
SET new_org_id = right(org_id,3);

Related

Add column to table with existing data in SQL Server

I have a table Rates with data in it and I need to add new column to the table however I get the error:
ALTER TABLE only allows columns to be added that can contain nulls, or have a DEFAULT definition specified, or the column being added is an identity or timestamp column, or alternatively if none of the previous conditions are satisfied the table must be empty to allow addition of this column. Column 'CreatedOn' cannot be added to non-empty table 'RateIncreases' because it does not satisfy these conditions
How can I do this, I have disabled prevent saving changes that required table re-creation
What part of the error do you not understand? When a column is added to an existing table, there are rows. The column is assigned to each of those rows. SQL Server has to give those rows a value. How does it do this?
It can assign the default value for the column.
It can assign NULL.
In your case, you have defined the column as NOT NULL but not provided a default value. Hence, the database does not know what to do, so it returns an error.
The simplest solution is to remove the NOT NULL constraint in the definition. Very close behind is assigning a default value.

performance impact of default value set on table's column in postgresql

if a table have default value on a column for e.g.
create table emp
(
flag smallint default 1
)
so is there any impact of this default column in bulk import , if I am not using in insert statement.
According to the docs:
Before 11:
Adding a column with a default requires updating each row of the table (to store the new column value). However, if no default is specified, PostgreSQL is able to avoid the physical update. So if you intend to fill the column with mostly nondefault values, it's best to add the column with no default, insert the correct values using UPDATE, and then add any desired default as described below.
source
11 and after:
From PostgreSQL 11, adding a column with a constant default value no longer means that each row of the table needs to be updated when the ALTER TABLE statement is executed. Instead, the default value will be returned the next time the row is accessed, and applied when the table is rewritten, making the ALTER TABLE very fast even on large tables. However, if the default value is volatile (e.g., clock_timestamp()) each row will need to be updated with the value calculated at the time ALTER TABLE is executed. To avoid a potentially lengthy update operation, particularly if you intend to fill the column with mostly nondefault values anyway, it may be preferable to add the column with no default, insert the correct values using UPDATE, and then add any desired default as described below.
source
If you take a look into the source for the generator/planner/optimizer/rewriter
( postgresql/src/backend/rewrite/rewriteHandler.c around line#1112, function build_column_default() ) :
The default value(or function, e.g. for serials) is fetched from the catalogs and added once to the query tree. So, the DEFAULT may even be more efficient than fetching separate values for all affected rows from one of the tables in query.
But you would have to measure the difference to be sure.

Disabling INSERT operations on Default Value Columns - SQL Server

In Sql Server 2008, I have a table that is filled by a data provider application.
I want to keep an "INSERT_DATE" column on table, so that I can know the date the record is inserted.
In order to do this, I defined a default constraint on INSERT_DATE column which puts GETDATE() by default.
However, I don't want this column value to be overwritten by data provider application.
So, how can I disable insert into INSERT_DATE column?
(I cannot use computed column. Because Clustered Index uses INSERT_DATE field)
You could use an After Insert trigger. That way, whatever is inserted into that column for an inserted row you could update to the current date/time.
You probably don't want the column updates as well when the row is subsequently updated.
Your best bet is to use a trigger. You might not be able to throw an error if the application provides a value but at least you will be able to set it right by skipping the column in the insert you specify in your trigger.

sql - retain calculated result in calculated field

certain fields in our database contain calculated functions e.g.
select lastname + ', ' + firstname as fullname from contact where contact.id =$contact$
when viewing the field the correct data is shown (i assume this is because when you open the record, the calculation is executed). however, the data is not 'stored' to the field, and therefore is null until the record is opened. is it possible to 'store' the result to the field, making it possible to search the data?
many thanks
james
EDIT
it is not possible for me to create computed_columns using our software.
the above field is a text feild where either 1) a user can manual type in the required data or 2) the database can generate the answer for you (but only whilst you are looking at the record). i know that if I run the following:
Select * from contact where contact.id =$contact$ for xml auto
i only get lastname, firstname - so i know that the fullname field does not retain its information.
If you are using computed columns in sql server, the column is already searchable regardless of whether the calculation result is stored or not. However, if you would like to make it so that the calculation is not run each time you read the row, you can change that under row properties in your Modify Table GUI.
Use the PERSISTED key word when you create the column
From BOL:
PERSISTED
Specifies that the SQL Server Database Engine will physically store the computed values in the table, and update the values when any other columns on which the computed column depends are updated. Marking a computed column as PERSISTED lets you create an index on a computed column that is deterministic, but not precise. For more information, see Creating Indexes on Computed Columns. Any computed columns that are used as partitioning columns of a partitioned table must be explicitly marked PERSISTED. computed_column_expression must be deterministic when PERSISTED is specified.
This isn't the way computed columns work in SQL Server, so I suspect this is something your client application is doing. How are you looking at the data when the value is computed correctly? Does it work when you view the data in SSMS?
Take a look at http://msdn.microsoft.com/en-us/library/ms191250(v=SQL.90).aspx to see how to create computed columns properly.
eg.
create table TestTable
(a int,
b int,
c as a + b)
insert into TestTable (a,b)
values (1,2)
select * from TestTable
where c = 3
This query is based on the computed column and it returns the row that's been inserted.
You need to use the PERSISTED option on a column when you use CREATE TABLE e.g.
CREATE TABLE test (col_a INT, col_b INT, col_c AS col_A * col_B PERSISTED)

SQL - How to ALTER COLUMN on a computed column

I'm working with SQL Server 2008. Is it possible to alter a computed column without actually dropping the column and then adding it again (which I can get to work)? For example, I have this table:
CREATE TABLE [dbo].[Prices](
[Price] [numeric](8,3) NOT NULL,
[AdjPrice] AS [Price] / [AdjFactor],
[AdjFactor] [numeric](8,3) NOT NULL)
Later realizing that I have a potential divide by zero error I want to alter the [Adjprice] column to handle this, but if I just drop the column and add it again, I lose the column order.
I want to do something like:
ALTER TABLE dbo.[Prices]
ALTER COLUMN [AdjPrice] AS (CASE WHEN [AdjFactor] = 0 THEN 0 ELSE [Price] / [AdjFactor] END)
But this isn't correct. If this is possible, or there is another solution, I would appreciate the help.
Unfortunately, you cannot do this without dropping the column first.
From MSDN:
ALTER COLUMN
Specifies that the named column is to be changed or altered. ALTER COLUMN is not allowed if the compatibility level is 65 or lower. For more information, see sp_dbcmptlevel (Transact-SQL).
The modified column cannot be any one of the following:
A computed column or used in a computed column.
if you must maintain order, copy the data into a duplicate table, then rebuild the table to keep your column order, then copy the data from the duplicate table back in.
Just be sure to do this when there is no activity going on.
NO
if it is computed, what is the big deal dropping it and adding it again? is it PERSISTED and there are million of rows?
I do not think you can alter this column with out dropping.
So drop the colum then add new column.
If you find out any other way to do this please tell me.
its easy to overcome divide by zero error
use
SELECT
( 100 / NULLIF( 0, 0 ) ) AS value
it will return a null, if 0 is in that column,
instead of alter go for update by using the above example
Also read the 3rd normalization for computed column