我在一栏中有以下内容:
MetaDataServe
-------------
MindWorks.Accounts
MindWorks.Transactions
MindWorks.Commissions
...
我需要将这些列更新为:
MindWorks.Client.Accounts
我最初想过使用字符串函数来更新它们(LEFT,SUBSTR等),但是有没有替代或更好的方法来更新列中的文本以插入文本?
我使用的是SQL Server 2008,无法使用CLR集成。
答案 0 :(得分:10)
这是一个关于“最快”的问题,因此下面提供了时间
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)
效果摘要 - STUFF> SUBSTRING> REPLACE 强>
update MetaDataServe set vc = STUFF(vc, 9, 0, '.Client')
SQL Server解析和编译时间:
CPU时间= 0 ms,经过时间= 3 ms 表'MetaDataServe'。扫描计数1,逻辑读取55402,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0
SQL Server执行时间:
CPU时间= 10094 ms,经过时间= 10808 ms CPU时间= 10250 ms,经过时间= 10896 ms。
(2次来自多次执行以显示可变性,它非常低,因此可以认为时间精确到3%以内)
update MetaDataServe set vc = REPLACE(vc, '.', '.Client.')
SQL Server解析和编译时间:
CPU时间= 3 ms,经过时间= 3 ms 表'MetaDataServe'。扫描计数1,逻辑读取55402,物理读取0,预读读取159,lob逻辑读取0,lob物理读取0,lob预读读取0
SQL Server执行时间:
CPU时间= 20469 ms,经过时间= 21238 ms。
update MetaDataServe set vc = 'MindWorks.Client.' + SUBSTRING(vc, 11, 100)
SQL Server解析和编译时间:
CPU时间= 0 ms,经过时间= 1 ms 表'MetaDataServe'。扫描计数1,逻辑读取55402,物理读取0,预读读取3,lob逻辑读取0,lob物理读取0,lob预读读取0
SQL Server执行时间:
CPU时间= 11219 ms,经过时间= 12030 ms CPU时间= 11531 ms,经过时间= 12148 ms。
(固定位置版本已在上面给出)
效果摘要 - 已修复> (PATINDEX = CHARINDEX)
PATINDEX与CHARINDEX之间似乎没有实质性差异
update MetaDataServe set vc = STUFF(vc, PATINDEX('%.%',vc), 0, '.Client')
SQL Server解析和编译时间:
CPU时间= 0 ms,经过时间= 2 ms 表'MetaDataServe'。扫描计数1,逻辑读取55400,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0
SQL Server执行时间:
CPU时间= 15218 ms,经过时间= 16167 ms。
update MetaDataServe set vc = STUFF(vc, CHARINDEX('.',vc), 0, '.Client')
SQL Server解析和编译时间:
CPU时间= 0 ms,经过时间= 3 ms 表'MetaDataServe'。扫描计数1,逻辑读取55402,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0
SQL Server执行时间:
CPU时间= 15469 ms,经过时间= 16353 ms。
即使STUFF速度更快,您也可能遇到棘手的情况。如果您的数据包含
"MindWorksNoDot"
您使用
进行更新update MetaDataServe set vc = STUFF(vc, CHARINDEX('.',vc), 0, '.Client')
你最终得到了NULL!因为当CHARINDEX找不到点时,STUFF的第二个参数为零(0)会导致整个字符串转到 NULL 。
为了安全性和可靠性,鉴于它只比STUFF方法慢33%,我只想使用REPLACE语句,即
update MetaDataServe set vc = REPLACE(vc, '.', '.Client.')
答案 1 :(得分:3)
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
在这两者中,STUFF可能更灵活。只是取决于你的需求。