很明显,省略 varchar 的长度是一件坏事。不幸的是,我现在正在使用发生这种情况的代码库。广泛地。我想纠正这一点。第一步是查找出现的情况。这就是我需要帮助的地方。
使用我能想到的所有同义词在各种网络引擎上进行搜索都没有返回权威答案。我要问的是
- 我错过的其他测试用例
- 一种全面、规范的查找无长度声明的方法
通常在 Windows 开发环境(SSMS、Powershell、.Net 等)上可用的任何技术都是好的。采用更多利基技术的答案对于更广泛的社区来说会很有趣,但对我个人来说就不那么有趣了。
测试
由于所讨论的四种数据类型 - char、nchar、varchar 和 nvarchar - 都以字符 CHAR 结尾,因此我在下面的测试中单独使用它。这可以避免列表变得臃肿,并使添加更多测试变得更简单。如果需要的话,复制-粘贴-替换会很容易。
-- These are all legal; the regex must not return these
char(9)
char (9) -- with a space
char (9) -- with a tab
char (9) -- tab space tab space
char(max)
char
(9) -- a new line between type and length
character(9)
CAST(999 AS character(9))
char varying(9)
character varying(9)
CAST(999 AS char varying(9))
CAST(999 AS character varying(9))
-- These also are legal; ugly, but legal
[char](9)
[char] (9) -- with a space
[char] (9) -- with a tab
[char] (9) -- tab space tab space
[char](max)
[char]
(9) -- a new line between type and length
-- The type can also be delimited by double-quote
"char"(9)
-- All the tests using square brackets should be duplicated with other delimiters.
[character](9)
CAST(999 AS [character](9))
-- SQL Server 2022 throws an error for [character varying]
-- Msg 243, Level 16, State 1, Line 15
-- Type character varying is not a defined system type.
-- These are business terms which the regex should not return
characteristic
charge
chart
-- These are valid SQL but missing the length. These are what the search should return
char;
char ; -- a space
char ; -- a tab
char,
char ,
char = 'lorem'
cast(9 as char)
convert(char, 9)
[char];
[char] ; -- a space
[char] ; -- a tab
[char],
[char] ,
[char] = 'lorem'
cast(9 as [char])
convert([char], 9)
character
CAST(999 AS character)
char varying
character varying
CAST(999 AS char varying)
CAST(999 AS character varying)
正则表达式不是解决此问题的正确方法。总会有不可能/极难发现的误报。例如,多行注释块
相反,我建议使用SqlScriptDOM,它是一个 .NET 库,用于解析 T-SQL 语句并与其 Microsoft 提供的抽象语法树进行交互。
然后,您可以使用 .NET 应用程序或 PowerShell 来准确识别丢失的字符大小。
您可以在源代码管理或sys.sql_modules中迭代代码库,并将内容传递给 ScriptDOM 函数。
我从Dan Guzman 的博客借用了大部分代码
这里我使用的是
TSql150Parser
,它根据兼容性级别表匹配 SQL Server 2019这将是输出
SQL Server Management Studio (SSMS) 允许在搜索中使用正则表达式。我在这方面的技能微乎其微。我有的是这个
char
是有问题的数据类型,后缀为 varchar 和 nvarchar。[^agt\(]
防止匹配上面列出的业务术语。我只包含了当前语料库所需的三个字母。在不同的应用中,这些术语可以被扩展或完全省略。我必须包含左括号(转义为\(
),否则char(..
会匹配。]?
允许零个或一个右方括号。\s*
允许零个、一个或多个空白字符。(?!)
是一个消极的前瞻。意思是“不跟随”。我真的只想要一个左括号,但必须创建一个( | | )
包含空格 (\s
) 和右方 () 的或列表 (\]
) 才能获得所需的匹配。这主要是由于反复试验造成的。贪婪/懒惰的评估尤其让我失望。我很想得到改进建议。
测试一下:
https://regex101.com/r/bTLmR9/3
附言。应单独检查错误。