Значения по умолчанию для SQL Server: почему с одной или двумя круглыми скобками?

если вы запустите этот script, чтобы получить все значения значений по умолчанию в базе данных:

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?

Ответ 1

Именно так SQL хранит их внутренне.

Они не нужны, за исключением случаев, когда IN по какой-либо причине расширяется до (.. OR ...).

Вы должны попробовать ограничить проверку с помощью AND и OR. Лордский лорд.

Ответ 2

Этот ответ и ответ ГБН достаточно. Тем не менее, 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
;

Я проверил несколько баз данных, и эти правила соблюдались. Однако мне было бы интересно посмотреть, увидят ли другие те же результаты.

Ответ 3

Интересно, что документация для SQL 20172014 по крайней мере)

показывает TSQL без скобок вообще

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