2016-01-08 2 views
1

Опытные фанаты SQL Server У меня проблема с устаревшей хранимой процедурой, которая находится внутри экземпляра SQL Server 2008 R2, который я унаследовал также с данными PROD, которые, по меньшей мере, являются ужасными. Кроме того, я НЕ могу вносить какие-либо изменения в данные и структуры таблиц.Вопрос об обновлении TSQL

Итак, вот моя проблема, хранимая процедура, о которой идет речь, работает ежедневно и используется для обновления таблицы employee. Как видно из моего примера, входящие данные (#New_Employees) содержат обновленные данные, и мне нужно использовать их для обновления данных в Employee данные хранятся в таблице #Existing_Employees. На протяжении многих лет использовалось различное форматирование значения EMP_ID и должно поддерживаться как есть (я сражался и проиграл это сражение). К счастью, я успешно изменил формат столбца EMP_ID в таблице #New_Employees (Да!), И любые новые записи будут использовать этот формат к счастью!

Итак, теперь вы можете увидеть мою проблему, мне нужно обновить ID столбец в таблице #New_Employees с соответствующим ID из таблицы #Existing_Employees путем сопоставления (правильно вы догадались) по EMP_ID колонн. Поэтому я придумал чрезвычайно хакерский способ обработки разрозненных форматов столбцов EMP_ID, но он очень медленный, учитывая количество строк, которые мне нужно обрабатывать (1M +).

Я думал о создании промежуточной таблицы, где я мог бы просто закиньте EMP_ID столбцов в INT, а затем обратно к NVARCHAR в каждой таблице, чтобы удалить начальные нули, и я вроде наклонившись, что путь, но я хотел бы видеть, если был другой способ справиться с этими дисфункциональными данными. Любые конструктивные комментарии приветствуются.

 IF OBJECT_ID(N'TempDB..#NEW_EMPLOYEES') IS NOT NULL 
      DROP TABLE #NEW_EMPLOYEES 

     CREATE TABLE #NEW_EMPLOYEES(
          ID INT 
          ,EMP_ID NVARCHAR(50) 
          ,NAME NVARCHAR(50)) 
     GO 

     IF OBJECT_ID(N'TempDB..#EXISTING_EMPLOYEES') IS NOT NULL 
      DROP TABLE #EXISTING_EMPLOYEES 

     CREATE TABLE #EXISTING_EMPLOYEES(
          ID INT PRIMARY KEY 
          ,EMP_ID NVARCHAR(50) 
          ,NAME NVARCHAR(50)) 
     GO 

     INSERT INTO #NEW_EMPLOYEES 
     VALUES(NULL, '00123', 'Adam Arkin') 
       ,(NULL, '00345', 'Bob Baker') 
       ,(NULL, '00526', 'Charles Nelson O''Reilly') 
       ,(NULL, '04321', 'David Numberman') 
       ,(NULL, '44321', 'Ida Falcone') 

    INSERT INTO #EXISTING_EMPLOYEES 
     VALUES(1, '123', 'Adam Arkin') 
       ,(2, '000345', 'Bob Baker') 
       ,(3, '526', 'Charles Nelson O''Reilly') 
       ,(4, '0004321', 'Ed Sullivan') 
       ,(5, '02143', 'Frank Sinatra') 
       ,(6, '5567', 'George Thorogood') 
       ,(7, '0000123-1', 'Adam Arkin') 
       ,(8, '7', 'Harry Hamilton') 

     -- First Method - Not Successful 
     UPDATE NE 
      SET ID = EE.ID 
     FROM 
      #NEW_EMPLOYEES NE 
       LEFT OUTER JOIN #EXISTING_EMPLOYEES EE 
        ON EE.EMP_ID = NE.EMP_ID 

     SELECT * FROM #NEW_EMPLOYEES 

     -- Second Method - Successful but Slow 
     UPDATE NE 
      SET ID = EE.ID 
     FROM 
      dbo.#NEW_EMPLOYEES NE 
       LEFT OUTER JOIN dbo.#EXISTING_EMPLOYEES EE 
        ON CAST(CASE WHEN NE.EMP_ID LIKE N'%[^0-9]%' 
         THEN NE.EMP_ID 
         ELSE LTRIM(STR(CAST(NE.EMP_ID AS INT))) END AS NVARCHAR(50)) = 
         CAST(CASE WHEN EE.EMP_ID LIKE N'%[^0-9]%' 
         THEN EE.EMP_ID 
         ELSE LTRIM(STR(CAST(EE.EMP_ID AS INT))) END AS NVARCHAR(50)) 

     SELECT * FROM #NEW_EMPLOYEES 
+1

Вы можете создавать индексированные представления для работы? Это даст вам возможность вычислить значения обрезанных или числовых идентификаторов, когда это возможно, один раз и проиндексировать их для повышения производительности. Любой шаблон 'like', который начинается с подстановочного знака, не сможет использовать индекс (за исключением более быстрого способа сканирования таблицы). [Ref] (https://msdn.microsoft.com/en-us/library/dd171921%28SQL.100%29.aspx) и [ref] (https://msdn.microsoft.com/en-us/library /ms191432%28v=sql.105%29.aspx). – HABO

+0

Нет, я застрял с тем, что у меня есть, они отказались вносить изменения. –

+1

Может ли человек, который проголосовал за этот пост, объясните? –

ответ

0

число строк, которые я должен обрабатывать (1M +).

Миллион сотрудников? В день?

Я думаю, что я хотел бы добавить 3-ю таблицу:

create table #ids (id INT not NULL PRIMARY KEY 
        , emp_id not NULL NVARCHAR(50) unique); 

занесения эту таблицу с помощью LTRIM(STR(CAST, гм, алгоритм и обновления сотрудников непосредственно с объединением этих трех таблиц.

Я рекомендую использовать ANSI обновления, а не от Microsoft нестандартного update ... from, так как версия ANSI предотвращает недетерминированные результаты в тех случаях, когда FROM производит более одной строки.

Смежные вопросы