SQL Server默认值:为什么有一个或两个括号?

时间:2010-05-26 10:12:29

标签: sql-server tsql

如果您运行此脚本以检索数据库中的所有默认值定义:

select 
    c.name as columnname, t.name as tablename, 
    d.definition as value, d.name as constraintname
from
    sys.default_constraints d
    join sys.columns c
        on d.parent_column_id = c.column_id
        and d.parent_object_id = c.object_id
    join sys.tables t
        on c.object_id = t.object_id

你会得到很多默认值,如:

(getdate())
((0))
('')
('2099-12-31')

我的问题是,为什么有括号?他们有必要吗?为什么有些值有一对,有些有两个?在编写T-SQL脚本时是否完全遵循计数?

3 个答案:

答案 0 :(得分:8)

这就是SQL如何在内部存储它们。

除了IN由于某种原因扩展到(.. OR ...)时,不需要它们。

您应该尝试使用AND和OR进行检查约束。 Lordy阁下。

答案 1 :(得分:0)

This answergbn's answer就足够了。但是,对于FWIW,我注意到至少在数据库中有一种模式,用于SQL Server将默认值存储在单括号和双括号中的方式。

  • 数字的双括号(在我的情况下为所有整数)。
  • 非数字(即字符串和函数)的单括号。
  • 所有定义至少存储在单个括号中。
  • 没有定义存储在两组以上的括号中。

尽管这可能不会影响功能等,但作为程序员,知道有一种模式感觉很好。

下面是一个查询,用于根据这些规则检查数据库中的默认值(这可能并不完美,但这只是一个开始)。

-- Find number of distinct defaults. This should match the number of records in following query 
-- to ensure all are accounted for.
select count(*) as NumberOfDistinctConstraints 
from (select distinct [definition] from sys.default_constraints) t
;

-- Find defaults that follow and don't follow the rules.
;with c1 as (
    select [definition] as DefaultValue, 3 as NumberOfParentheses
    from sys.default_constraints dc
    where [definition] like '(((%'

    union

    select [definition], 2
    from sys.default_constraints dc
    where [definition] like '(([^(]%'

    union

    select [definition], 1
    from sys.default_constraints dc
    where [definition] like '([^(]%' --and ([definition] like '(N''%' or [definition] like '(''%')

    union

    select [definition], 0
    from sys.default_constraints dc
    where [definition] like '[^(]%'
)
, c2 as (
    select 
        DefaultValue
        , NumberOfParentheses
        , case
            when 
                NumberOfParentheses >= 3 -- None exists.
                or NumberOfParentheses = 0 -- None exists.
                or (
                    -- Any double parentheses not followed by a digit or negative sign.
                    NumberOfParentheses = 2 
                    and substring(DefaultValue, 3, 1) not like ('[0-9]') 
                    and substring(DefaultValue, 3, 1) not like ('-')
                )
                or (
                    -- Any single parenthesis followed by a digit or negative sign.
                    NumberOfParentheses = 1 
                    and (
                        substring(DefaultValue, 2, 1) like ('[0-9]') 
                        and substring(DefaultValue, 2, 1) like ('-')
                    )
                )
            then
                0
            else 1
        end as FollowsTheRules
    from c1
)
select *
from c2
--where FollowsTheRules = 0
order by FollowsTheRules asc, NumberOfParentheses desc, DefaultValue asc
;

我检查了一些数据库,这些规则成立了。但是,我很想看看其他人是否也看到相同的结果。

答案 2 :(得分:0)

有趣的是documentation for SQL 2017(至少2014

显示TSQL 完全没有括号

CREATE TABLE dbo.doc_exz (
  column_a INT,
  column_b INT DEFAULT 50);