Sql server ROSS APPLY正在做什么,或者交叉应用操作符通常是如何工作的?如果是前者,JM_7是完全正确的。它从字符串中剥离出空格和分号。如果数据的其余部分有其他非整型字符,则应将其展开以剥离这些字符。如果是晚些时候,这个话题对几百个字符来说太大了。。。以下是伊

Sql server ROSS APPLY正在做什么,或者交叉应用操作符通常是如何工作的?如果是前者,JM_7是完全正确的。它从字符串中剥离出空格和分号。如果数据的其余部分有其他非整型字符,则应将其展开以剥离这些字符。如果是晚些时候,这个话题对几百个字符来说太大了。。。以下是伊,sql-server,tsql,sql-server-2008-r2,sql-server-2016,Sql Server,Tsql,Sql Server 2008 R2,Sql Server 2016,ROSS APPLY正在做什么,或者交叉应用操作符通常是如何工作的?如果是前者,JM_7是完全正确的。它从字符串中剥离出空格和分号。如果数据的其余部分有其他非整型字符,则应将其展开以剥离这些字符。如果是晚些时候,这个话题对几百个字符来说太大了。。。以下是伊兹克·本·甘的几段非常好的视频。这真的很值得花时间去看它们,@AskMe-Mt-answer已经更新为允许默认值,我添加了与大表的批量更新相关的注释和代码。您只考虑了时间格式:[time]如“[0-9][0-9][0-9][0-9][0-9][


ROSS APPLY正在做什么,或者交叉应用操作符通常是如何工作的?如果是前者,JM_7是完全正确的。它从字符串中剥离出空格和分号。如果数据的其余部分有其他非整型字符,则应将其展开以剥离这些字符。如果是晚些时候,这个话题对几百个字符来说太大了。。。以下是伊兹克·本·甘的几段非常好的视频。这真的很值得花时间去看它们,@AskMe-Mt-answer已经更新为允许默认值,我添加了与大表的批量更新相关的注释和代码。您只考虑了时间格式:[time]如“[0-9][0-9][0-9][0-9][0-9][0-9]”。其他时间格式呢?我是否应该单独设置每个时间格式?而且,在执行SET@r=@@ROWCOUNT时,while循环似乎会一次又一次地继续运行;是不是每一行用该条件更新后@@ROWCOUNT都将为0?您对此有何想法?@AskMe当然,您必须对所需的每一种时间格式执行此操作。因此,您将得到3个循环和3个支持索引。至于ROWCOUNT,在没有要更新的行之后,它将是0,循环将结束。
 Time
----------
23:44:33
12:17 09
20 00 20
  :  :  
111913
    Time
   --------
   23:44:33
   12:17:09
   20:00:20
   21:12:00  
   11:19:13
    Update [dbo].[table] 
   set [TIME] = '21:14:00'
   WHERE [TIME] = '  :  :  '


   Update [dbo].[table]
   set [time] = replace([TIME], ' ','')  
   WHERE [time]   like '[0-9][0-9] [0-9][0-9] [0-9][0-9]'

      Update [dbo].[table]
      set [time] = STUFF(STUFF([TIME],3,0,':'),6,0,':')
      WHERE [time] like '[0-9][0-9][0-9][0-9][0-9][0-9]'

Update [dbo].[table]
    set [time] = replace([time], ' ', ':')
    WHERE [time] like '[0-9][0-9]:[0-9][0-9] [0-9][0-9]'
DECLARE @r INT;

WHILE @r > 0
BEGIN
   Update TOP (50000) [dbo].[table]
   set [time] = replace([TIME], ' ','')  
   WHERE [time]   like '[0-9][0-9] [0-9][0-9] [0-9][0-9]';

   SET @r = @@ROWCOUNT;
   -- when there is no rows left @@ROWCOUNT will be 0
END;
CREATE NONCLUSTERED INDEX IDX_dbo_table_time
  ON [dbo].[table] ([time] ASC) 
  WHERE [time] like '[0-9][0-9] [0-9][0-9] [0-9][0-9]';
SET NOCOUNT ON;

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData;

CREATE TABLE #TestData (
    TimeVal VARCHAR(20)
    );
INSERT #TestData (TimeVal) VALUES
    ('23:44:33'),
    ('12:17 09'),
    ('20 00 20'),
    ('  :  :  '),
    ('111913'),
    ('12:17'),
    ('12:   09'),
    ('  :17 09');

-- before values...
SELECT [Before] = td.TimeVal FROM #TestData td;

-- update problem values...
UPDATE td SET  
    td.TimeVal = CASE LEN(rr.TimeVal)
                    WHEN 6 THEN STUFF(STUFF(rr.TimeVal, 5, 0, ':'), 3, 0, ':')
                    ELSE '21:12:00'
                END
FROM
    #TestData td
    CROSS APPLY ( VALUES (REPLACE(REPLACE(td.TimeVal, ' ', ''), ':', '')) ) rr (TimeVal)
WHERE 
    td.TimeVal NOT LIKE '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]';

-- after values...
SELECT [After] = td.TimeVal FROM #TestData td;
Before
--------------------
23:44:33
12:17 09
20 00 20
  :  :  
111913
12:17
12:   09
  :17 09

After
--------------------
23:44:33
12:17:09
20:00:20
21:12:00
11:19:13
21:12:00
21:12:00
21:12:00
-- create a log table to make it easy to know where you arw in the update process.
CREATE TABLE dbo.TimeValUpdate_LOG (
    BegID INT,
    EndID INT,
    RowsUpdated INT,
    BegTime DATETIME,
    EndTime DATETIME,
    SecsToComplete AS DATEDIFF(SECOND, BegTime, EndTime)
    );

-- update script...
DECLARE 
    @BegID INT = 0,
    @EndID INT = 500000,
    @BegTime DATETIME,
    @EndTime DATETIME;


WHILE EXISTS (SELECT 1 FROM dbo.RealTable rt WHERE rt.PrimaryKey  > @BegID)
BEGIN
    BEGIN TRY
        BEGIN TRANSACTION; 
        --===================================
        SET @BegTime = CURRENT_TIMESTAMP;
        INSERT dbo.TimeValUpdate_LOG (BegID, EndID, BegTime) VALUES (@BegID, @EndID, @BegTime);
        --=============================================================================

            -- update problem values...
            UPDATE rt SET  
                rt.TimeVal = CASE LEN(rr.TimeVal)
                                WHEN 6 THEN STUFF(STUFF(rr.TimeVal, 5, 0, ':'), 3, 0, ':')
                                ELSE '21:12:00'
                            END
            FROM
                dbo.RealTable rt
                CROSS APPLY ( VALUES (REPLACE(REPLACE(rt.TimeVal, ' ', ''), ':', '')) ) rr (TimeVal)
            WHERE 
                rt.PrimaryKey >= @BegID
                AND rt.PrimaryKey < @EndID
                AND rt.TimeVal NOT LIKE '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]';

        --=============================================================================
        UPDATE tul SET
            tul.RowsUpdated = @@ROWCOUNT,
            tul.EndTime = CURRENT_TIMESTAMP
        FROM 
            dbo.TimeValUpdate_LOG tul
        WHERE 
            tul.BegID = @BegID
            AND tul.EndID = @EndID;
        --===================================
        SET @BegID = @EndID + 1;
        SET @EndID = @BegID + 500000;
        --===================================
        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;

            DECLARE @ErrorNumber INT = ERROR_NUMBER();
            DECLARE @ErrorLine INT = ERROR_LINE();
            DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE();
            DECLARE @ErrorSeverity INT = ERROR_SEVERITY();
            DECLARE @ErrorState INT = ERROR_STATE();

            PRINT 'Actual error number: ' + CAST(@ErrorNumber AS VARCHAR(10));
            PRINT 'Actual line number: ' + CAST(@ErrorLine AS VARCHAR(10));

            RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
    END CATCH;
END;
create trigger trCorrectTime on [table] after insert
as
    update [table] set [time] = '21:14:00'
    from [table]
    join inserted on inserted.id=[table].id
    where inserted.[TIME] = '  :  :  '

    update [table] set [time] = STUFF(STUFF([table].[time],3,0,':'),6,0,':')
    from [table]
    join inserted on inserted.id=[table].id
    where inserted.[time] like '[0-9][0-9][0-9][0-9][0-9][0-9]'

    update [table] set [time] = replace([table].[time], ' ',':')  
    from [table]
    join inserted on inserted.id=[table].id
    where inserted.[time] like '[0-9][0-9]_[0-9][0-9]_[0-9][0-9]'
go