Опытные фанаты 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
Вы можете создавать индексированные представления для работы? Это даст вам возможность вычислить значения обрезанных или числовых идентификаторов, когда это возможно, один раз и проиндексировать их для повышения производительности. Любой шаблон '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
Нет, я застрял с тем, что у меня есть, они отказались вносить изменения. –
Может ли человек, который проголосовал за этот пост, объясните? –