Insert and initialize a SQL column with value dependent on another column data - sql-server

I am completely new to writing SQL scripts and could use a little help. I need to create a script that will run only once and add a column to an existing table. This column needs to have a value directly dependent to another column's value. The value is based on whether the other column's text value contains some text.
For instance, I need a way of saying for the following value "MNA-HLTH-CAR":
if (tableValue.contains("HLTH")) {
newColumn.insert("Health"); //Insert new column value Health
} else if (tableValue.contains......
At my attempt thus far I have:
ALTER TABLE [table_name]
ADD [new_element] varchar(5)
IF
CONTAINS([column_name], "HLTH")
I probably am horrible off, and could use some help. Thanks!

If the column is always dependant, and you're using a DBMS that supports it, you can use a computed column. For SQL Server, that looks like:
alter table YourTable
add YourColumn as
(
case
when OtherColumn like '%Health%' then 'HLTH'
else 'Default'
end
)
To add a real column with values, you could use a two-step approach. After adding the column:
alter table YourTable
add YourColumn varchar(5)
Run an update query to set its value:
update YourTable
set YourColumn =
case
when OtherColumn like '%Health%' then 'HLTH'
else 'Default'
end
That should initialize the new column. But unlike the computed column, it's now up to you to maintain it.

Related

Is NULL necessary?

Is NULL or NOT NULL necessary for Adding a column in SQL Server? (If you are going to run UPDATE statement after)
I tested without it locally, and it seems to work fine both in SQL and on the website; but I wanted to make sure before running release/production.
I looked up some other articles, including microsoft website. Some show it with, some without. SO articles say some benefits of NULL, like if you have information that may be added later. But assuming I am going to run UPDATE to add values after, will it matter?
I am guessing it does not matter from what I've tested and read.
ALTER TABLE [dbo].[MyTable] ADD NewColumn varchar(150);
UPDATE [dbo].[MyTable] SET NewColumn ='Math' WHERE ID = 1
UPDATE [dbo].[MyTable] SET NewColumn ='Science' WHERE ID = 2
You can skip it, and by default the column will be created as NULL. However it is more legible if you indicate it explicitly.
Keep in mind that if your table already has data, you CANNOT add the column as NOT NULL. For this, you should firstly add the column as NULL, then UPDATE the values with non-null valid data and then alter column to NOT NULL.
Edit: Assuming the default behavior of the sql server when adding columns.
You don't have to write it, when you skip it column will be created as 'NULL'.
Following statements are equal:
ALTER TABLE [dbo].[MyTable] ADD NewColumn varchar(150);
ALTER TABLE [dbo].[MyTable] ADD NewColumn varchar(150) NULL;
If you want to add a column and DB engine should guarantee you that this new column will be always populated you can add a NOT NULL column with a default value.
Other option will be to change the column to NOT NULL after the update.
I'd make sure you have something declarative. And if you are setting as "not null," be sure you have a default value or use can suffer LOTS of data loss if data previously exists. It makes me nervous because this an ALTER vs a CREATE.

How to manipulate the TEXT column of DELETED/INSERTED tables in SQL Server trigger

I have a SQL Server table and I need to code a trigger to fire when there is an update on that table.
There is a Text column in this table. I need to compare the old and new value of that column after the update, from the INSERTED and DELETED tables.
The thing is that I absolutely can't change the type of that column.
Does anyone have found a way to bypass this restriction in a SQL Server trigger ?
Instead of a trigger would it possible for you to amend your update query? Here's an example update that returns the before and after values:
-- Declare a table to hold our sample data.
DECLARE #Example TABLE
(
TextField VARCHAR(255)
)
;
-- Populate it.
INSERT INTO #Example
(
TextField
)
VALUES
('a'),
('b'),
('c')
;
-- Update the text field and view the change
UPDATE
#Example
SET
TextField = 'z'
OUTPUT
deleted.TextField AS Old_TextField,
inserted.TextField AS New_TextField
;
You could also use the INTO clause to capture this output into a new table.
For more on the INSERTED and DELETED tables see MSDN.
I decided to do something else, I don't really like it, but it allows me to use a varchar column instead of the text column. So I did this :
ALTER TABLE [MyTable]
ADD [MyVarcharColumn] AS (CONVERT([nvarchar(MAX)],[MyTextColumn]))
With this computed column, I don't need to edit any existing queries or .EDMX (Entity Framework) of an existing project, and my trigger works fine.

SQL Server add auto serial id to additional field during insert

I have an insert statement in a stored procedure who's primary key is a serial id. I want to be able to populate an additional field in the same table during the same insert statement with the serial id used for the primary key. Is this possible?
Unfortunately this is a solution already in place... I just have to implement it.
Regards
I can't imagine a reason why you would want a copy of the key in another column. But in order to do it, I think you'll need to follow your update with a statement to get the value of the identity key, and then an update to put that value in the other column. Since you're already in a stored procedure, it's probably ok to have a few extra statements, instead of doing it in the very same one.
DECLARE #ID INT;
INSERT INTO TABLE_THINGY (Name, Address) VALUES ('Joe Blow', '123 Main St');
SET #ID = SCOPE_IDENTITY();
UPDATE TABLE_THINGY SET IdCopy = #Id WHERE ID = #ID
If it's important that this be done every single time, you might want to create a Trigger to do it; beware, however, that many people hate triggers because of the obfuscation and difficulty in debugging, among other reasons.
http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/
I agree, it is odd that you would replicate the key within the same table but with that said you could use a trigger, thus making it have no impact to current insert statements.
The below trigger is "After Insert" so technically it happens milliseconds after the insert if you truly wanted it to happen at the same time you would use a FOR INSERT instead and just replicate the logic used to create the serial id field into the new field.
CREATE TRIGGER triggerName ON dbo.tableName
AFTER INSERT
AS
BEGIN
update dbo.tableName set newField = inserted.SerialId where serialId = inserted.SerialId
END
GO
You could have a computed column that just returns the id column.
CREATE TABLE dbo.Products
(
ProductID int IDENTITY (1,1) NOT NULL
, OtherProductID AS ProductID
);
Having said that, data should only live in one place and to duplicate it in the same table is just a wrong design.
No, you cannot use the same insert statement for identity Id and copy that auto generated Id to the same row.
Multi-Statement using OUTPUT inserted or Trigger is your best bet.

How to change column datatype in SQL Server database without losing data?

I have SQL Server database and I just realized that I can change the type of one of the columns from int to bool.
How can I do that without losing the data that is already entered into that table?
You can easily do this using the following command. Any value of 0 will be turned into a 0 (BIT = false), anything else will be turned into 1 (BIT = true).
ALTER TABLE dbo.YourTable
ALTER COLUMN YourColumnName BIT
The other option would be to create a new column of type BIT, fill it from the old column, and once you're done, drop the old column and rename the new one to the old name. That way, if something during the conversion goes wrong, you can always go back since you still have all the data..
ALTER TABLE tablename
ALTER COLUMN columnname columndatatype(size)
Note: if there is a size of columns, just write the size also.
If it is a valid change.
you can change the property.
Tools --> Options --> Designers --> Table and Database designers --> Uncheck --> Prevent saving changes that required table re-creation.
Now you can easily change the column name without recreating the table or losing u r records.
if you use T-SQL(MSSQL); you should try this script:
ALTER TABLE [Employee] ALTER COLUMN [Salary] NUMERIC(22,5)
if you use MySQL; you should try this script:
ALTER TABLE [Employee] MODIFY COLUMN [Salary] NUMERIC(22,5)
if you use Oracle; you should try this script:
ALTER TABLE [Employee] MODIFY [Salary] NUMERIC(22,5)
Why do you think you will lose data? Simply go into Management Studio and change the data type. If the existing value can be converted to bool (bit), it will do that. In other words, if "1" maps to true and "0" maps to false in your original field, you'll be fine.
Go to Tool-Option-designers-Table and Database designers and Uncheck Prevent saving option
for me , in sql server 2016, I do it like this
*To rename column Column1 to column2
EXEC sp_rename 'dbo.T_Table1.Column1', 'Column2', 'COLUMN'
*To modify column Type from string to int:( Please be sure that data are in the correct format)
ALTER TABLE dbo.T_Table1 ALTER COLUMN Column2 int;
Alter column data type with check type of column :
IF EXISTS(
SELECT 1
FROM sys.columns
WHERE NAME = 'YourColumnName'
AND [object_id] = OBJECT_ID('dbo.YourTable')
AND TYPE_NAME(system_type_id) = 'int'
)
ALTER TABLE dbo.YourTable ALTER COLUMN YourColumnName BIT
In compact edition will take size automatically for datetime data type i.e. (8) so no need to set size of field and generate error for this operation...
I can modify the table field's datatype, with these following query: and also in the Oracle DB,
ALTER TABLE table_name
MODIFY column_name datatype;
Replace datatype without losing data
alter table tablename modify columnn newdatatype(size);

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