У меня есть таблица MyTextstable (myTextsTable_id INT, myTextsTable_text VARCHAR(MAX))
. В этой таблице содержится около 4 миллионов записей, и я пытаюсь удалить любой экземпляр символов ASCII
в следующих диапазонах (44): VARCHAR(MAX)
, столбец myTextsTable_text
.SQL-запрос работает нормально в SQL Server 2012, но не удалось выполнить в SQL Server 2008 R2
- 00 - 08
- 11 - 12
- 14 - 31
Я написал следующий SQL запрос, который берет за 10 минут на SQL Server 2012, но не удалось выполнить на SQL Server 2008 R2 даже через два часа (поэтому я остановил выполнение). Обратите внимание: я восстановил резервную копию базы данных SQL Server 2008 R2 на SQL Server 2012 (т. Е. Данные точно такие же).
BEGIN TRANSACTION [Tran1]
BEGIN TRY
UPDATE myTextsTable
SET myTextsTable_text = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(myTextsTable_text, CHAR(0), ''), CHAR(1), ''), CHAR(2), ''), CHAR(3), ''), CHAR(4), ''), CHAR(5), ''), CHAR(6), ''), CHAR(7), ''), CHAR(8), ''), CHAR(11), ''), CHAR(12), ''), CHAR(14), ''), CHAR(15), ''), CHAR(16), ''), CHAR(17), ''), CHAR(18), ''), CHAR(19), ''), CHAR(20), ''), CHAR(21), ''), CHAR(22), ''), CHAR(23), ''), CHAR(24), ''), CHAR(25), ''), CHAR(26), ''), CHAR(27), ''), CHAR(28), ''), CHAR(29), ''), CHAR(30), ''), CHAR(31), ''), CHAR(127), '')
WHERE myTextsTable_text LIKE '%[' + CHAR(0) + CHAR(1) + CHAR(2) + CHAR(3) + CHAR(4) + CHAR(5) + CHAR(6) + CHAR(7) + CHAR(8) + CHAR(11) + CHAR(12) + CHAR(14) + CHAR(15) + CHAR(16) + CHAR(17) + CHAR(18) + CHAR(19) + CHAR(20) + CHAR(21) + CHAR(22) + CHAR(23) + CHAR(24) + CHAR(25) + CHAR(26) + CHAR(27) + CHAR(28) + CHAR(29) + CHAR(30) + CHAR(31) + CHAR(127) + ']%';
COMMIT TRANSACTION [Tran1];
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [Tran1];
--PRINT ERROR_MESSAGE();
END CATCH;
Включено только 135 записей. Поскольку единственный запрос UPDATE
не работал в SQL Server 2008, я попробовал следующий подход с временной таблицей.
BEGIN TRANSACTION [Tran1]
BEGIN TRY
IF OBJECT_ID('tempdb..#myTextsTable') IS NOT NULL DROP TABLE #myTextsTable;
SELECT myTextsTable_id, myTextsTable_text
INTO #myTextsTable
FROM myTextsTable
WHERE myTextsTable_text LIKE '%[' + CHAR(0) + CHAR(1) + CHAR(2) + CHAR(3) + CHAR(4) + CHAR(5) + CHAR(6) + CHAR(7) + CHAR(8) + CHAR(11) + CHAR(12) + CHAR(14) + CHAR(15) + CHAR(16) + CHAR(17) + CHAR(18) + CHAR(19) + CHAR(20) + CHAR(21) + CHAR(22) + CHAR(23) + CHAR(24) + CHAR(25) + CHAR(26) + CHAR(27) + CHAR(28) + CHAR(29) + CHAR(30) + CHAR(31) + CHAR(127) + ']%';
UPDATE #myTextsTable
SET myTextsTable_text = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(myTextsTable_text, CHAR(0), ''), CHAR(1), ''), CHAR(2), ''), CHAR(3), ''), CHAR(4), ''), CHAR(5), ''), CHAR(6), ''), CHAR(7), ''), CHAR(8), ''), CHAR(11), ''), CHAR(12), ''), CHAR(14), ''), CHAR(15), ''), CHAR(16), ''), CHAR(17), ''), CHAR(18), ''), CHAR(19), ''), CHAR(20), ''), CHAR(21), ''), CHAR(22), ''), CHAR(23), ''), CHAR(24), ''), CHAR(25), ''), CHAR(26), ''), CHAR(27), ''), CHAR(28), ''), CHAR(29), ''), CHAR(30), ''), CHAR(31), ''), CHAR(127), '')
UPDATE myTextsTable
SET myTextsTable_text = new.myTextsTable_text
FROM myTextsTable
INNER JOIN #myTextsTable new ON new.myTextsTable_id=myTextsTable.myTextsTable_id
DROP TABLE #myTextsTable;
COMMIT TRANSACTION [Tran1];
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [Tran1];
--PRINT ERROR_MESSAGE();
END CATCH;
Однако результат такой же. Работает отлично в SQL Server 2012, но не в SQL Server 2008 R2. Я обнаружил, что запрос UPDATE
все еще выполнялся даже через два часа (записи были сохранены в таблице темпа (#myTextsTable
) через несколько минут, я проверил это позже, чтобы убедиться, что какая часть занимает больше времени).
Поскольку вышеупомянутые два способа не работали, я попытался использовать это с использованием переменных TABLE
, чтобы проверить, не имеет значения, но результат был таким же (т.е. отлично работает в SQL Server 2012, но не в SQL Server 2008 R2)
BEGIN TRANSACTION [Tran1]
BEGIN TRY
DECLARE @myTextsTable TABLE (myTextsTable_id INT, myTextsTable_text VARCHAR(MAX))
INSERT INTO @myTextsTable(myTextsTable_id, myTextsTable_text)
SELECT myTextsTable_id, myTextsTable_text
FROM myTextsTable
WHERE myTextsTable_text LIKE '%[' + CHAR(0) + CHAR(1) + CHAR(2) + CHAR(3) + CHAR(4) + CHAR(5) + CHAR(6) + CHAR(7) + CHAR(8) + CHAR(11) + CHAR(12) + CHAR(14) + CHAR(15) + CHAR(16) + CHAR(17) + CHAR(18) + CHAR(19) + CHAR(20) + CHAR(21) + CHAR(22) + CHAR(23) + CHAR(24) + CHAR(25) + CHAR(26) + CHAR(27) + CHAR(28) + CHAR(29) + CHAR(30) + CHAR(31) + CHAR(127) + ']%';
UPDATE @myTextsTable
SET myTextsTable_text = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(myTextsTable_text, CHAR(0), ''), CHAR(1), ''), CHAR(2), ''), CHAR(3), ''), CHAR(4), ''), CHAR(5), ''), CHAR(6), ''), CHAR(7), ''), CHAR(8), ''), CHAR(11), ''), CHAR(12), ''), CHAR(14), ''), CHAR(15), ''), CHAR(16), ''), CHAR(17), ''), CHAR(18), ''), CHAR(19), ''), CHAR(20), ''), CHAR(21), ''), CHAR(22), ''), CHAR(23), ''), CHAR(24), ''), CHAR(25), ''), CHAR(26), ''), CHAR(27), ''), CHAR(28), ''), CHAR(29), ''), CHAR(30), ''), CHAR(31), ''), CHAR(127), '')
UPDATE myTextsTable
SET myTextsTable_updated = GETDATE()
,myTextsTable_updatedby = 'As per V87058'
,myTextsTable_text = new.myTextsTable_text
FROM myTextsTable
INNER JOIN @myTextsTable new ON new.myTextsTable_id=myTextsTable.myTextsTable_id
COMMIT TRANSACTION [Tran1];
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [Tran1];
--PRINT ERROR_MESSAGE();
END CATCH;
Может ли кто-нибудь объяснить, почему это произошло? Как заставить этот SQL-запрос работать в SQL Server 2008 R2?
Примечание: Я знаю, что строковые манипуляции на сервере/слое базы данных не идеальны, и было бы желательно выполнять строковые манипуляции на прикладном уровне, а затем сохранять их в БД. Но я пытаюсь понять, почему это проблема в одной версии и почему не в другой версии.
SQL Server 2012
Microsoft SQL Server 2012 - 11.0.5058.0 (X64)
Standard Edition (64-разрядная версия) на Windows NT 6.3 (Build 9600:) (гипервизор)SQL Server 2008 R2
Microsoft SQL Server 2012 - 11.0.5058.0 (X64)
Standard Edition (64-разрядная версия) на Windows NT 6.3 (Build 9600:) (гипервизор)
Вместо переменной таблицы попробуйте TempTable. –
@ SelvaTS: Спасибо за ваш комментарий. Я попробовал временную таблицу перед тем, как попробовать ее с помощью TABLE vatable, как упоминалось в моем вопросе. – Sathish
Это может быть довольно долго, но я попытаюсь разделить на 30 запросов (или с помощью цикла) для замены символов один за другим: 'UPDATE myTextsTable SET myTextsTable_text = REPLACE (myTextsTable_text, CHAR (0), ' ') WHERE myTextsTable_text LIKE'% ['+ CHAR (0) +']% '; ', чтобы избежать слишком большого количества исправленных REPLACE. И в этом случае, возможно, CHARINDEX вместо LIKE. – Rubik