【问题标题】:Create rule to restrict special characters in table in sql server创建规则以限制sql server中表中的特殊字符
【发布时间】:2014-08-20 15:17:01
【问题描述】:

我想创建一个规则来限制将特殊字符输入到列中。 我尝试了以下方法。但是没用。

CREATE RULE rule_spchar
AS
@make LIKE '%[^[^*|\":<>[]{}`\( );@&$]+$]%'

我不知道我在这里做错了什么。任何帮助将不胜感激。

【问题讨论】:

标签: sql sql-server sql-server-2008 sql-server-2008-r2


【解决方案1】:

您可以在此列上创建Check Constraint,并且只允许在此列中插入NumbersAlphabets,见下文:

检查约束以仅允许数字和字母

ALTER TABLE Table_Name 
ADD CONSTRAINT ck_No_Special_Characters 
       CHECK (Column_Name NOT LIKE '%[^A-Z0-9]%') 

检查约束以仅允许数字

ALTER TABLE Table_Name 
ADD CONSTRAINT ck_Only_Numbers 
       CHECK (Column_Name NOT LIKE '%[^0-9]%') 

检查约束以仅允许字母

ALTER TABLE Table_Name 
ADD CONSTRAINT ck_Only_Alphabets 
       CHECK (Column_Name NOT LIKE '%[^A-Z]%') 

【讨论】:

  • 很有趣,但你能做一个能阻止^*|\\":&lt;&gt;[]{}`\( );@&amp;$]+$的吗?
  • 除了 (Column_Name NOT LIKE '%[^A-Z]%') 不仅限于字母,而且仅限于拉丁/西方风格的字母(但是,它将允许土耳其例如,i 或德语变音符号,它不是 ASCII 字符)...如果您只想要 ascii 字符,请更改列排序规则,并使用检查约束排除数字。哦,这里不会提到中国人有3种表示数字的方式(西方,传统符号,正式符号),而印度人(真正的)也使用其他数字符号。如果只需要整数,请将类型设置为整数...
  • 你有理由使用NOT LIKE,结合正则表达式中的否定(^ 符号),而不是仅仅使用LIKE '[A-Z0-9]' 或者LIKE '^[A-Z0-9]$' 吗?
  • @sanderd17 x LIKE '[A-Z]' 只匹配一个单个字符(隐含的len(x) = 1 必须为真)并且禁止使用x LIKE '[A-Z]' OR x LIKE '[A-Z][A-Z]' OR ..。没有办法使用像(哈哈!)* 修饰符和LIKE 这样的正则表达式。 LIKE 的模式产生非常有限,并且不涉及正则表达式,即使^ 也用于其他(正则表达式)上下文。双重否定找到“任何未批准的字符”,然后仅在“没有(即没有未批准的字符)”的情况下认为输入有效。
【解决方案2】:

请务必记住 Microsoft 针对您正在使用或打算使用的功能的计划。 CREATE RULE 是一个已弃用的功能,不会长期存在。考虑改用CHECK CONSTRAINT

此外,由于字符排除类实际上并不像 RegEx 那样运行,因此如果不多次调用 LIKE,就不可能以这种方式排除括号 []。因此,整理到不区分重音的整理并使用包含字母数字的过滤器会更成功。非拉丁字母需要做更多的工作。

M.Ali 的NOT LIKE '%[^A-Z0-9 ]%' 应该很好用。

【讨论】:

    【解决方案3】:

    M.Ali 的回答代表了您描述的解决方案的最佳实践。话虽这么说,我以不同的方式阅读了您的问题(即,您执行类似比较的方式有什么问题。)

    1. 您没有正确转义通配符。
    2. 表达式'AB' LIKE '%[AB]% 为真。表达式'ZB' LIKE '%[^AB]%' 也是正确的,因为该语句等同于'Z' LIKE '[^AB]' OR 'A' LIKE '[^AB]' 相反,您应该使用'YZ' NOT LIKE '%[^AB]%',它等同于'Y' NOT LIKE '%[^AB]%' AND 'Z' NOT LIKE '%[^AB]%'
    3. 您没有转义单引号或不可见字符。看看ASCII characters. 你会更好地实施像 M.Ali's 这样的解决方案并添加你希望排除的任何字符

    以下脚本演示了由特殊字符组成的复杂通配符语句的形成。

    -- Create sample data
    -- Experiment testing various characters
    DECLARE @temp TABLE (id INT NOT NULL, string1 varchar(10) NOT NULL)
    
    INSERT INTO @temp
            (id,string1)
    SELECT 1, '12]34'
    UNION 
    SELECT 2, '12[34'
    UNION 
    SELECT 3, '12_34'
    UNION 
    SELECT 4, '12%34'
    UNION 
    SELECT 5, '12]34'
    
    SET NOCOUNT ON
    DECLARE @SQL_Wildcard_Characters VARCHAR(512),
    @Count_SQL_Wildcard_Characters INT,
    @Other_Special_Characters VARCHAR(255),
    @Character_Position INT,
    @Escape_Character CHAR(1),
    @Complete_Wildcard_Expression VARCHAR(1024)
    SET @Character_Position = 1
    
    -- Note these need to be escaped: 
    SET @SQL_Wildcard_Characters = '[]^%_'
    -- Choose an escape character.  
    SET @Escape_Character = '~'
    -- I added the single quote (') ASCII 39 and the space ( ) ASCII 32.  
    -- You could also add the actual characters, but this approach may make it easier to read.
    SET @Other_Special_Characters = '*|\":<>{}`\();@&$' + CHAR(39) + CHAR(32)
    
    -- Quick loop to escape the @SQL_Wildcard_Characters
    SET @Count_SQL_Wildcard_Characters = LEN(@SQL_Wildcard_Characters)
    WHILE @Character_Position < 2*@Count_SQL_Wildcard_Characters
    BEGIN
        SET @SQL_Wildcard_Characters = STUFF(@SQL_Wildcard_Characters,@Character_Position,0,@Escape_Character)
        SET @Character_Position = @Character_Position + 2
    END
    -- Concatenate the respective strings
    SET @Complete_Wildcard_Expression = @SQL_Wildcard_Characters+@Other_Special_Characters
    
    -- Shows how the statment works for match
    SELECT ID, string1, @Complete_Wildcard_Expression AS [expression]
    FROM @temp
    WHERE string1 LIKE '%['+@Complete_Wildcard_Expression+']%' ESCAPE @Escape_Character
    
    -- Show how the statement works fo non-match
    SELECT ID, string1, @Complete_Wildcard_Expression AS [expression]
    FROM @temp
    WHERE string1 NOT LIKE '%[^'+@Complete_Wildcard_Expression+']%' ESCAPE @Escape_Character
    

    【讨论】:

      【解决方案4】:
      CREATE FUNCTION udf_checkspecial_characters(@String varchar(MAX))
      RETURNS INT AS
      BEGIN
      DECLARE @Result INT;
      SELECT @Result=(CASE WHEN @String COLLATE Latin1_General_BIN LIKE '%[(<~!@/#$%^&>)]%' THEN 1 ELSE 0 END);
      RETURN @Result;
      END
      

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。您可以在帮助中心找到更多关于如何写好答案的信息:stackoverflow.com/help/how-to-answer。祝你好运?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-08
      • 2017-11-06
      • 1970-01-01
      相关资源
      最近更新 更多