整理已声明的SQL变量

13

我一直在查看下面复制的这段代码,它用于查找非ASCII字符...

select line,
  patindex('%[^ !-~]%' COLLATE Latin1_General_BIN, Line) as [Position],
  substring(Line, patindex('%[^ !-~]%' COLLATE Latin1_General_BIN, Line), 1) as [InvalidCharacter],
  ascii(substring(line, patindex('%[^ !-~]%' COLLATE Latin1_General_BIN, Line), 1)) as [ASCIICode]
from staging.APARMRE1
where patindex('%[^ !-~]%' COLLATE Latin1_General_BIN, Line) > 0

我突然想声明一个变量 '%[^ !-~]%' COLLATE Latin1_General_BIN,以便每次不必再重复写出它。

declare @regex varchar(20) = '%[^ !-~]%' COLLATE Latin1_General_BIN;

select line,
  patindex(@regex, Line) as [Position],
  substring(Line, patindex(@regex, Line), 1) as [InvalidCharacter],
  ascii(substring(line, patindex(@regex, Line), 1)) as [ASCIICode]
from staging.APARMRE1
where patindex(@regex, Line) > 0

它就是不能做同样的事情,是我缺少一些语法吗?这是不可能的吗?

1个回答

18

这是正常的。当您创建一个变量时,它会使用数据库的默认排序规则。

DECLARE @regex varchar(20) = '%[^ !-~]%' COLLATE Latin1_General_BIN;

您的字符串使用COLLATE Latin1_General_BIN,被隐式转换为与数据库默认排序规则相同的字符串。


例如,数据库是不区分大小写的。 我使用您的语法创建一个区分大小写的数据库,并检查其元数据:

DECLARE @v1 varchar(100) = 'ABC' COLLATE Latin1_General_CS_AS;

SELECT name, collation_name
FROM sys.dm_exec_describe_first_result_set(
    N'SELECT @v1 AS [@v1]', N'@v1 varchar(100)', 0);

LiveDemo


输出:
╔══════╦══════════════════════════════╗
║ name ║        collation_name        ║
╠══════╬══════════════════════════════╣
║ @v1  ║ SQL_Latin1_General_CP1_CI_AS ║
╚══════╩══════════════════════════════╝

变量(不包括表变量中的列)不允许定义排序规则,因此没有以下语法:

DECLARE @v1 varchar(100) COLLATE Latin1_General_CS_AS = 'ABC' ;
-- Incorrect syntax near the keyword 'COLLATE'.

关于您提到的异常:表变量... 当涉及到表类型时,如果我将数据传递到具有特定排序规则的表类型中,它会将我的输入数据转换为表类型列定义的排序规则吗? - ColinMac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接