I have the following in a column:
MetaDataServe
-------------
MindWorks.Accounts
MindWorks.Transactions
MindWorks.Commissions
...
I need to update those columns to be in the form of:
MindWorks.Client.Accounts
I initially thought of using the string functions to update them (LEFT, SUBSTR etc), but is there an alternative or better method of updating text in a column to insert text?
I am using SQL Server 2008 and can't use CLR integration.
No. If you really need this, you will have to generate ID manually.
Analyzing the execution plan may help to resolve performance bottlenecks of the update query. We can remove the redundant indexes on the table. As possible as we need to use the WHERE clause in our update statements. If it is possible we have to disable the delete triggers when we perform an update statement.
First, specify the table name that you want to change data in the UPDATE clause. Second, assign a new value for the column that you want to update. In case you want to update data in multiple columns, each column = value pair is separated by a comma (,). Third, specify which rows you want to update in the WHERE clause.
This is a question about "fastest", so timings are provided below
create table MetaDataServe (id int identity primary key, vc varchar(max));
insert MetaDataServe values
('MindWorks.Accounts'),
('MindWorks.Transactions'),
('MindWorks.Commissions');
insert MetaDataServe
select vc
from MetaDataServe, master..spt_values a, master..spt_values b
where b.number between 1 and 30
-- (1090110 row(s) affected)
Performance Summary - STUFF > SUBSTRING > REPLACE
update MetaDataServe set vc = STUFF(vc, 9, 0, '.Client')
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 3 ms.
Table 'MetaDataServe'. Scan count 1, logical reads 55402, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 10094 ms, elapsed time = 10808 ms.
CPU time = 10250 ms, elapsed time = 10896 ms.
(the 2 times are from multiple executions to show the variability, it is quite low so the times can be considered accurate to within 3%)
update MetaDataServe set vc = REPLACE(vc, '.', '.Client.')
SQL Server parse and compile time:
CPU time = 3 ms, elapsed time = 3 ms.
Table 'MetaDataServe'. Scan count 1, logical reads 55402, physical reads 0, read-ahead reads 159, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 20469 ms, elapsed time = 21238 ms.
update MetaDataServe set vc = 'MindWorks.Client.' + SUBSTRING(vc, 11, 100)
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 1 ms.
Table 'MetaDataServe'. Scan count 1, logical reads 55402, physical reads 0, read-ahead reads 3, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 11219 ms, elapsed time = 12030 ms.
CPU time = 11531 ms, elapsed time = 12148 ms.
(The fixed position version is already given above)
Performance Summary - FIXED > (PATINDEX = CHARINDEX)
There appears to be no material difference between PATINDEX and CHARINDEX
update MetaDataServe set vc = STUFF(vc, PATINDEX('%.%',vc), 0, '.Client')
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 2 ms.
Table 'MetaDataServe'. Scan count 1, logical reads 55400, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 15218 ms, elapsed time = 16167 ms.
update MetaDataServe set vc = STUFF(vc, CHARINDEX('.',vc), 0, '.Client')
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 3 ms.
Table 'MetaDataServe'. Scan count 1, logical reads 55402, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 15469 ms, elapsed time = 16353 ms.
Even though STUFF is faster, you can get into tricky situations. If your data contains
"MindWorksNoDot"
And you update using
update MetaDataServe set vc = STUFF(vc, CHARINDEX('.',vc), 0, '.Client')
You end up with NULL! Because when CHARINDEX cannot find the dot, the second parameter to STUFF of zero (0) causes the entire string to go to NULL.
For safety and reliability, given it is only 33% slower than the STUFF approach, I would simply use a REPLACE statement, i.e.
update MetaDataServe set vc = REPLACE(vc, '.', '.Client.')
WITH sample AS (
SELECT 'MindWorks.Accounts' AS col
UNION ALL
SELECT 'MindWorks.Transactions'
UNION ALL
SELECT 'MindWorks.Commissions')
SELECT s.col,
STUFF(s.col, CHARINDEX('.', s.col), 1, '.Client.') AS col2
FROM sample s
WITH sample AS (
SELECT 'MindWorks.Accounts' AS col
UNION ALL
SELECT 'MindWorks.Transactions'
UNION ALL
SELECT 'MindWorks.Commissions')
SELECT s.col,
REPLACE(s.col, '.', '.Client.') AS col2
FROM sample s
col col2
--------------------------------------------------------
MindWorks.Accounts MindWorks.Client.Accounts
MindWorks.Transactions MindWorks.Client.Transactions
MindWorks.Commissions MindWorks.Client.Commissions
Of the two, STUFF is likely to be more flexible. Just depends on your needs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With