如何通过块更新巨大的记录块

时间:2016-02-18 06:54:18

标签: sql sql-server tsql

我有大约500 000的数据。我需要将名字和第二名的数据更新为大写字母

我的样本资料:

declare @T table(Firstname varchar(max),Secondname varchar(max))
insert into @T values ('ch bhaskar rao ','sridhar kolla ')
insert into @T values ('hemanth kumar','varun chenna-reddy')
insert into @T values ('mohan vara prasad','raju t d p durga raju')
insert into @T values ('police mutual','police mutual')

我的剧本:

;WITH CTE AS (
    select (
        select upper(T.N.value('.', 'char(1)')),
            lower(stuff(T.N.value('.', 'varchar(max)'), 1, 1, ''))+(CASE WHEN RIGHT(T.N.value('.', 'varchar(max)'), 1)='-' THEN '' ELSE ' ' END)
        from X.Secondname.nodes('/N') as T(N)
        for xml path(''), type
    ).value('.', 'varchar(max)') As Secondname
    from 
    (
        select 
         cast('<N>'+replace(replace(replace(Secondname, ' ', '</N><N>'),' ', '</N><N>'),'-','-</N><N>')  +'</N>' as xml) as Secondname
        from @T
    ) as X 
)
UPDATE T 
SET
    Secondname = C.Secondname
FROM 
    CTE C 
    INNER JOIN @T T 
        ON   T.Secondname = C.Secondname

Select Secondname from @T 

当数据大约有10 000条记录时工作正常,但当我试图更新大约500万条记录时,系统会被挂起。如何通过像10000这样的块再次更新块,以便系统不会负担?

4 个答案:

答案 0 :(得分:1)

考虑@t表是数据库中的物理表。

此方法将具有最少的日志记录。

;WITH CTE
     AS (SELECT (SELECT Upper(T.N.value('.', 'char(1)')),
                        Lower(Stuff(T.N.value('.', 'varchar(max)'), 1, 1, '')) + ( CASE
                                                                                     WHEN RIGHT(T.N.value('.', 'varchar(max)'), 1) = '-' THEN ''
                                                                                     ELSE ' '
                                                                                   END )
                 FROM   X.Secondname.nodes('/N') AS T(N)
                 FOR xml path(''), type).value('.', 'varchar(max)') AS Secondname
         FROM   (SELECT Cast('<N>'
                             + Replace(Replace(Replace(Secondname, ' ', '</N><N>'), ' ', '</N><N>'), '-', '-</N><N>')
                             + '</N>' AS XML) AS Secondname
                 FROM   @T) AS X)

select  ISNULL(C.Secondname,T.Secondname) into TEMP_TABLE
FROM   CTE C
       RIGHT JOIN @T T
               ON T.Secondname = C.Secondname

在新的temp_table

中重新创建索引和约束

现在将temp_table重命名为旧表名

exec sp_rename original_table, original_table_bck -- to rename the original table name to another name 
exec sp_rename temp_table, original_table

答案 1 :(得分:1)

您可以像下面提到的那样更新表格:

declare @i int = 2
declare @j int = 1

    while @j > 0 
        begin 
            begin transaction
            update top (@i) a
            set a.firstname = upper(a.firstname),
                a.secondname = upper(a.secondname)
            from aa as a
            where a.firstname collate latin1_general_cs_as <> upper(a.firstname)
            set @j = @@rowcount
            commit transaction

        end

您可以根据需要更改上述代码。如果这有帮助,请告诉我。

答案 2 :(得分:-1)

为什么要更新数据库中名字和姓氏的起始字符?您可以在使用

显示CSS时处理它
text-transform: capitalize;

答案 3 :(得分:-1)

试试这个;这将有助于您解决问题 运行下面的功能,然后

SELECT dbo.InitCap
       (Firstname
       ), dbo.InitCap
       (Secondname
       )
FROM @t;

IF OBJECT_ID('InitCap') IS NOT NULL
    DROP FUNCTION InitCap;
GO
CREATE FUNCTION [dbo].[InitCap]
                               (
                @InputString VARCHAR(4000)
                               )
RETURNS VARCHAR(4000)
AS
     BEGIN
         DECLARE @Index INT;
         DECLARE @Char CHAR(1);
         DECLARE @PrevChar CHAR(1);
         DECLARE @OutputString VARCHAR(255);
         SET @OutputString = LOWER(@InputString);
         SET @Index = 1;
         WHILE @Index <= LEN(@InputString)
             BEGIN
                 SET @Char = SUBSTRING(@InputString, @Index, 1);
                 SET @PrevChar = CASE
                                     WHEN @Index = 1
                                     THEN ' '
                                     ELSE SUBSTRING(@InputString, @Index-1, 1)
                                 END;
                 IF @PrevChar IN
                                 (' ', ';', ':', '!', '?', ',', '.', '_', '-', '/', '&', '''', '('
                                 )
                     BEGIN
                         IF @PrevChar != ''''
                            OR UPPER(@Char) != 'S'
                             SET @OutputString = STUFF(@OutputString, @Index, 1, UPPER(@Char));
                     END;
                 SET @Index = @Index + 1;
             END;
         RETURN @OutputString;
     END;
GO