整理声明的SQL变量

时间:2015-12-04 20:15:54

标签: sql sql-server tsql collate

我一直在查看下面转载的this code,,它会查找非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 个答案:

答案 0 :(得分:6)

这很正常。创建变量时,它会对数据库采用默认排序规则。

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

带有COLLATE Latin1_General_BIN的字符串隐式投放到您的数据库默认排序规则的字符串。

<小时/> 例如,数据库是Case-Insensitive。我使用您的语法创建区分大小写的语法并检查它的元数据:

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'.