【发布时间】:2015-03-05 17:35:08
【问题描述】:
我有一张名为MyTextstable (myTextsTable_id INT, myTextsTable_text VARCHAR(MAX)) 的表。该表有大约 400 万条记录,我正在尝试删除 VARCHAR(MAX) 列 myTextsTable_text 以下范围内的任何 ASCII 字符实例。
- 00-08
- 11 - 12
- 14 - 31
- 127
我编写了以下 SQL 查询,在 SQL Server 2012 上执行不到 10 分钟,但在 SQL Server 2008 R2 上执行两小时后仍无法执行(所以我停止了执行)。请注意,我已在 SQL Server 2012 上恢复了 SQL Server 2008 R2 数据库的备份(即数据完全相同)。
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)
Windows NT 6.3(内部版本 9600:)上的标准版(64 位) (管理程序)SQL Server 2008 R2
Microsoft SQL Server 2012 - 11.0.5058.0 (X64)
Windows NT 6.3(内部版本 9600:)上的标准版(64 位) (管理程序)
【问题讨论】:
-
用 TempTable 代替 Table 变量。
-
@SelvaTS:感谢您的评论。如我的问题中所述,我在尝试使用 TABLE vatable 之前尝试过临时表。
-
它可能会更长,但我会尝试分成大约 30 个查询(或使用循环),以逐个替换字符:
UPDATE myTextsTable SET myTextsTable_text = REPLACE(myTextsTable_text, CHAR(0), '') WHERE myTextsTable_text LIKE '%[' + CHAR(0) + ']%';,这将避免太多的重叠代替。而且,在这种情况下,可能是 CHARINDEX 而不是 LIKE。 -
@Rubik:这在船上,我现在正在尝试。感谢您的评论。
标签: sql sql-server tsql sql-server-2008-r2 sql-server-2012