删除名称中包含不可打印字符的表格

Thi*_*lle 15 sql-server-2008 sql-server ddl

我有一个旧表,其名称包含不可打印的字符(CHAR(31),具体来说)。

不可打印的字符位于下划线旁边,我发现快捷方式CTRL+SHIFT+_创建了该CHAR(31)字符(这意味着“美国” - 单位分隔符)。以前的开发人员可能会错误地使用这个组合,并创建了包含这个奇怪字符的表格。

当我们SELECT对表发出命令时,它会返回结果。但是,当我们试图发出反对任何DDL( ,DROPsp_rename等),字符会导致一个问题。

例子:

DROP TABLE Table_Name;
Run Code Online (Sandbox Code Playgroud)

提高:

消息 15225 - 在当前数据库 'MyDB' 中找不到名为 'Table_Name' 的项目,因为@itemtype 被输入为 '(null)'。

EXEC sp_rename N'Table_Name', N'NewTableName'; 
Run Code Online (Sandbox Code Playgroud)

提高:

消息 102 - '_Name' 附近的语法不正确。

我已经用正确的名称复制了表,并在相关对象上更正了它。剩下的步骤就是将它从数据库中删除。

只是一个见解:当我们从 SQL Server 复制+粘贴到 Notepad++ 时,它会在表名中间显示隐藏字符(“US”),在下划线旁边:

单位分隔符 (CHAR(31)) 字符

Aar*_*and 19

由于您已经知道隐藏了哪个字符,您可以使用变量轻松构造当前名称,将其传递给sp_rename,然后使用新获取的名称删除表:

DECLARE @t nvarchar(128) = N'dbo.Table' + NCHAR(31) + N'_Name';
EXEC sys.sp_rename @t, N'NewTableName', N'OBJECT';
DROP TABLE dbo.NewTableName;
Run Code Online (Sandbox Code Playgroud)

(始终小心使用正确的架构标识符。)

更简单的方法是将您知道其中包含该字符的字符串放入方括号中。这对我来说很好用:

DROP TABLE dbo.[Table_Name];
---------------------^
-- There is an NCHAR(31) right before the underscore
Run Code Online (Sandbox Code Playgroud)

如果您不知道有问题的字符,您可以从目录视图中提取名称,通过周围的字符识别它,然后遍历字符以确定哪些有问题。这是一个完整的再现:

USE tempdb;
GO

DECLARE @sql NVARCHAR(MAX);
SET @sql = N'CREATE TABLE dbo.[Table' + NCHAR(31) + N'_Name](ID INT);';
EXEC sys.sp_executesql @sql;
GO

DECLARE @var NVARCHAR(128);
SELECT @var = name 
  FROM sys.tables 
  WHERE name LIKE N'Table%Name';

-- is it the right one?
PRINT @var;

DECLARE @i INT;
SET @i = 1;
WHILE @i <= LEN(@var)
BEGIN
  PRINT SUBSTRING(@var, @i, 1) + N' => ' + RTRIM(UNICODE(SUBSTRING(@var, @i, 1)));
  SET @i = @i + 1;
END
Run Code Online (Sandbox Code Playgroud)

结果:

Table_Name
T => 84
a => 97
b => 98
l => 108
e => 101
 => 31
_ => 95
N => 78
a => 97
m => 109
e => 101
Run Code Online (Sandbox Code Playgroud)

然后不要忘记责备或殴打负责以这种方式进入系统的桌子的人,如果他们仍然在该行业工作。