Update table column with data from other columns in same row - sql-server

I have a table that has several columns of textual data. The goal is to concatenate those columns into a single different column in the same table and same row.
What is the SQL Server query syntax that would allow me to do this?

Something like this:
UPDATE myTable SET X = Y + Z

Do you absolutely have to duplicate your data? If one of the column values changes, you will have to update the concatenated value.
A computed column:
alter table dbo.MyTable add ConcatenatedColumn = ColumnA + ColumnB
Or a view:
create view dbo.MyView as
select ColumnA, ColumnB, ColumnA + ColumnB as 'ConcatenatedColumn'
from dbo.MyTable
Now you can update ColumnA or ColumnB, and ConcatenatedColumn will always be in sync. If that's the behaviour you need, of course.

Might be misunderstanding but:
Alter table myTable add combinedColumn Varchar(1000);
Update myTable set combinedColumn = textField1 + textField2;

select
textfield1 + textfield2 + ... + textfieldN as conc_text,
otherfield1,
otherfield2,
...
otherfieldN
from
mytable

Related

Computed column vs Updates in SQL Server

I would like to know if there any performance boost for computed columns in SQL Server, please check the example below.
Now I have a stored procedure in production environment that updates tables, concatenating two VARCHAR columns into another column, which is NULL when created.
If I would like to switch the updating logic to using a computed column, which will automatically generate the value when loading the data.
Question is: will this help me to boost the process time for that derived column? I cannot really make the changes and test in the production environment at this point, but before I do that, in general, any advantages using computed columns vs updates.
Please note the updated column will remain as it is and the total number of records in effect will be up to million.
UPDATES:
Table definition
CREATE TableA
(
ColumnA VARCHAR(50),
ColumnB VARCHAR(50),
ColumnC VARCHAR(50)
)
ColumnA and ColumnB will be populated with data from SSIS package, and ColumnC will updated by the stored procedure, which is
UPDATE TableA
SET ColumnC = ISNULL(ColumnA,'') + ISNULL(ColumnB,'')
These updates will affect about up to millions of records.
If I would like to use:
CREATE TableA
(
ColumnA VARCHAR(50),
ColumnB VARCHAR(50),
ColumnC as ISNULL(ColumnA,'') + ISNULL(ColumnB,'')
)
will this be quicker for populating the ColumnC?
On the update I suggest a where so you don't update rows that do not need to be updated. An update takes a lock and puts an entry in the transaction log.
UPDATE TableA
SET ColumnC = ISNULL(ColumnA,'') + ISNULL(ColumnB,'')
WHERE ColumnC <> ISNULL(ColumnA,'') + ISNULL(ColumnB,'')
You can control growing the transaction log with:
(this is from memory so may have syntax error(s))
select 1
while (##rowcount > 0)
begin
UPDATE top(10000) TableA
SET ColumnC = ISNULL(ColumnA,'') + ISNULL(ColumnB,'')
WHERE ColumnC <> ISNULL(ColumnA,'') + ISNULL(ColumnB,'')
end
Computed Column
Computed column is a virtual column unless it is persisted. So if you don't persist then there is no extra time to load ColumnA and ColumnB. Select on ColumnC will be slower as it is computed on the fly.
If ColumnC is persisted will be like the update but done on the fly when ColumnA or ColumnB are inserted or updated.
As stated in comments a computed column is consistent. An update is only consistent up to the last time the command was run.

Can you update a column with a select statement in one query

For example right now I have three queries. An insert and select statement for one table:
INSERT INTO Table_A (col_1)
VALUES (val_1)
and
SELECT SUM(col_1)
FROM Table_A
WHERE Table_A_ID = id
After each insert I need to recalculate the sum and update the column of Table_B.
That sum is stored in a variable, 'sum', (I'm using dapper), and then passed to another function along with an 'id' variable which updates a column of Table_B.
UPDATE Table_B
SET col_1 = #sum
WHERE Table_B_ID = #id
I'd like to combine the last two queries to effectively achieve something like:
UPDATE Table_B
SET col_1 = (SELECT Sum(col_1) FROM Table_A WHERE Table_A_ID = id)
WHERE Table_B_ID = id
Is this possible?
Is this what you are looking for?
UPDATE #Table_B
SET col_1 = a.col_1
FROM (SELECT SUM(col_1) AS col_1 FROM #Table_A WHERE a.[id] = #id) a
WHERE [id] = #id
Is it really necessary to store a calculated column ?
If it is, you could consider creating a trigger on Table A that is executed each time a record is inserted in 'A'. The trigger could then update table_B with the calculated sum.
(Keep in mind that you'll have to modify the calculated sum in Table-B when a record in Table-A is deleted or updated as well. The trigger should thus be an AFTER INSERT, UPDATE, DELETE trigger.)

How to frame insert statements from select statement data in SQL Server?

I've selected some data from a table it gives some rows in as result. Now, I want to generate insert statements from result data in SQL Server.
Please suggest me any solutions.
If the destination table is a new table,
you may use SQL SELECT INTO Statement.
We can copy all columns into the new table:
SELECT *
INTO newtable [IN externaldb]
FROM table1;
Or we can copy only the columns we want into the new table:
SELECT column_name(s)
INTO newtable [IN externaldb]
FROM table1;
The new table will be created with the column-names and types as defined in the SELECT statement. You can apply new names using the AS clause.
Like this,
SELECT 'insert into tabledestination (col1destination,col2destination)
values (' + col1source + ',' + col2source + ')'
FROM tablesource;

Trigger that inserts only updated column names

I have created trigger that inserts names of the columns changed (insert, update, delete) in the audit table.
I have problem when I update columns. Lets say I have a table dbo.TABLE with columns COL1, COL2, COL3.
Further, lets say that I only have one row:
COL1 | COL2 | COL3
---------------------------
value1 | value2 | value3
If my update statement looks like this:
Update dbo.TABLE set COL1 = 'test1', COL2 = 'test2';
In my audit table will be inserted:
UPDATED
-------
COL1, COL2
This is OK, but lets say I have same table dbo.TABLE with first values (value1, value2, value3).
If my update statement looks like this:
Update dbo.TABLE set COL1 = 'value1', COL2 = 'test2';
In my audit table same result will be inserted as above (COL1, COL2).
How can I alter my trigger so only updated column (COL2) will be inserted?
I need some kind of statement that will check value of column before updating.
My trigger is too big to put all of it here, so I will only put part of the code that returns columns updated.
SELECT #idTable = T.id
FROM sysobjects P JOIN sysobjects T ON P.parent_obj = T.id
WHERE P.id = ##procid
SELECT #Columns_Updated = ISNULL(#Columns_Updated + ', ', '') + name
FROM syscolumns t
WHERE id = #idTable
AND CONVERT(VARBINARY,REVERSE(COLUMNS_UPDATED())) & POWER(CONVERT(BIGINT, 2), colorder - 1) > 0
This is original post from where I have taken the code:
SQL Server Update Trigger, Get Only modified fields
Are you able to prevent updates if the values are identical? This would be the best approach, and allow you to use the same code you have in your trigger (not to mention far more efficient from an i/o perspective).
If the front end driving the updates is a UI, then I would drop a logging class in it to record before/after data using that.
Failing that, I think (someone else might correct me here) you'd need to use CDC (change data capture) to compare old/new values.

Use SELECT result for another query

Is there any way other than using a cursor that I can use SELECT results for a subsequent INSERT/UPDATE query?
Something like:
DECLARE #SELECTRESULT;
SELECT Something into #SELECTRESULT
FROM Somewhere
INSERT INTO SomewhereElse (X, XX, XXX)
SELECT Something, GETDATE(), 'XXX'
FROM #SELECTRESULT
UPDATE Somewhere
Set SomethingElse = 'ABC'
WHERE
Something in
(SELECT Something FROM #SELECTRESULT)
The reason is that I have a relatively complex query from multiple tables and I don't want duplicate this code, once for the insert and second time for the update.
You can use a table variable.
Something like
DECLARE #Table TABLE(
Col1 INT
)
INSERT INTO #Table
SELECT Col1
FROM Table
Have a look at
Table Variables In T-SQL
DECLARE #local_variable (Transact-SQL)
Just use a temporary table it's ok for your case :
SELECT Something into #temporary_table FROM Somewhere WHERE blabla
use a temp table.
CREATE TABLE #tempTable
(
Something int NOT NULL,
CurrentDate DateTime NULL,
XXX Varchar(50)
)
Then use your complex query on multiple tables and insert the result set into the tempTable.
Insert into #tempTable
-- Complex Select Query
Just make sure that the columns returned by the selected query match in the order as per the #tempTable structure. Also the number of columns should match.
Once you have #tempTable with the complex data, you can use it multiple number of times for insert and update queries.
INSERT INTO SomewhereElse (X, XX, XXX)
SELECT * from #tempTable
UPDATE Somewhere
Set SomethingElse = 'ABC'
WHERE
Something in (SELECT Something FROM #tempTable)
DECLARE #SELECTRESULT table(Something nvarchar(50)) --the data that you could reuse.
insert into #SELECTRESULT(Something)
SELECT Something
FROM Somewhere
INSERT INTO SomewhereElse (X, XX, XXX)
SELECT Something, GETDATE(), 'XXX'
FROM #SELECTRESULT
UPDATE Somewhere
Set SomethingElse = 'ABC'
WHERE Something in
(SELECT Something FROM #SELECTRESULT)

Resources