SQL Server의 SYSNAME 데이터 형식은 무엇입니까?


131

SQL Server SYSNAME 데이터 유형은 무엇입니까? BOL의 말 :

sysname 데이터 형식은 개체 이름을 저장하는 테이블 열, 변수 및 저장 프로 시저 매개 변수에 사용됩니다.

그러나 나는 그것을 정말로 얻지 못한다. 제공 할 수있는 사용 사례가 있습니까?


1
아래의 훌륭한 답변 외에도 sys.types를 사용하여 열 메타 데이터를 얻으려는 사람이 nvarchar와 동일한 system_type_id를 공유하기 때문에 혼란을 일으키는 데 사용되었습니다.
StingyJack

답변:


150

sysnameIIRC라는 128 개의 유니 코드 문자로 제한된 내장 데이터 유형으로, 스크립트를 만들 때 주로 객체 이름을 저장하는 데 사용됩니다. 그 가치는NULL

기본적으로 사용하는 것과 같습니다 nvarchar(128) NOT NULL

편집하다

의견에서 @Jim이 언급했듯이 sysname정직 하게 사용할 비즈니스 사례가 실제로 있다고 생각하지 않습니다 . 주로 sysSQL Server 내 에서 내부 테이블 및 저장 프로 시저를 작성할 때 Microsoft에서 사용합니다 .

예를 들어, 실행 Exec sp_help 'sys.tables'하면 열 name이 다음과 같이 정의되어 있음을 알 수 있습니다. sysname이 값은 실제로 그 자체로 개체이기 때문에 (테이블)

나는 그것에 대해 너무 걱정할 것입니다.

SQL Server 6.5 이하 버전을 사용하는 사람들 (아직 사람들이 사용하고 있습니까?)에 내장 된 유형 sysname은 다음과 같습니다.varchar(30)

선적 서류 비치

sysname는 비고 섹션에서 nchar및에nvarchar 대한 문서를 통해 정의됩니다 .

sysnamenvarchar (128) 과 기능적으로 동등한 시스템 제공 사용자 정의 데이터 유형 이며 널 입력 가능하지 않습니다. sysname 은 데이터베이스 오브젝트 이름을 참조하는 데 사용됩니다.

위의 설명을 명확히하기 위해 기본적으로 sysnameNOT NULLnullable로 정의 할 수 있으므로 정의됩니다. 정확한 정의는 SQL Server 인스턴스마다 다를 수 있습니다.

특수 데이터 유형 사용

를 sysname 데이터 형식은 테이블 열 변수를 사용하고, 저장하는 오브젝트 이름 절차 파라미터들을 저장한다. sysname 의 정확한 정의는 식별자 규칙과 관련이 있습니다. 따라서 SQL Server 인스턴스마다 다를 수 있습니다. sysname 은 기본적으로 sysname 이 NULL이 아님을 제외하고 nvarchar (128) 와 기능적으로 동일 합니다. 이전 버전의 SQL Server에서 sysname 은 varchar (30)로 정의됩니다.

sysname허용 또는 거부 에 대한 추가 정보는 https://stackoverflow.com/a/52290792/300863NULL 에서 확인할 수 있습니다.

그것이 기본값 (NOT NULL이 아니기 때문에)이 될 것이라고 보장하지는 않습니다!


1
"제공 할 수있는 사용 사례가 있습니까?" 나는 당신이 사용하는 실질적인 비즈니스 이유를 찾지 못할 것이라고 생각합니다. 주로 테이블 등에서 상당히 많이 사용되므로 MS SQL에서 내부적으로 사용됩니다.
Jim

9
당신이 사용하는 것이 sysname스크립트 앞으로 (뒤로)의 호환성을 위해.
Martin Smith

여기에 2 센트를 넣으면 nvarchar(max)SP에서 null이 아닌 열로 선언 되었지만 sysnamesys 테이블 에는 으로 표시됩니다 .
gloomy.penguin

3
@Barry 사실 ...에 따라 sys.types그것은이다 nvarchar(256) not null. 시스템 유형 ID = 231 (nvarchar)입니다. 요즘은 TDS에서 유형 별명으로 작동합니다. 별칭의 첫 번째 ID는 256이며 이는에 해당합니다 sysname. 사용법은 : sysname정보 스키마에 사용됩니다.
atlaste

2
@atlaste sys.tables의 최대 길이는 바이트입니다. nvarchar는 문자 당 2 바이트를 사용하므로 nvarchar (128)로 정의됩니다.
David Rushton

60

제공 할 수있는 사용 사례가 있습니까?

동적 SQL 을 작성해야하는 경우 sysname테이블 이름, 열 이름 및 서버 이름을 보유하는 변수의 데이터 유형 으로 사용하는 것이 좋습니다.


6

참고로 ....

select * from sys.types where system_type_id = 231 두 줄을 제공합니다.

(이것이 아직 무엇을 의미하는지는 모르겠지만 지금은 내 코드를 망쳐 놓고 100 % 확신합니다)

편집 : 나는이 상황 (나의 상황) 또는 아마도 user_type_id와 esystem_type_id 모두에서 user_type_id에 가입해야한다는 것이 무엇을 의미하는지 추측합니다.

name        system_type_id   user_type_id   schema_id   principal_id    max_length  precision   scale   collation_name                  is_nullable     is_user_defined     is_assembly_type    default_object_id   rule_object_id
nvarchar    231              231            4           NULL            8000        0           0       SQL_Latin1_General_CP1_CI_AS    1               0                   0                   0                   0
sysname     231              256            4           NULL            256         0           0       SQL_Latin1_General_CP1_CI_AS    0               0                   0                   0                   0

create procedure dbo.yyy_test (
    @col_one    nvarchar(max),
    @col_two    nvarchar(max)  = 'default',
    @col_three  nvarchar(1),
    @col_four   nvarchar(1)    = 'default',
    @col_five   nvarchar(128),
    @col_six    nvarchar(128)  = 'default',
    @col_seven  sysname  
)
as begin 

    select 1
end 

이 쿼리는

select  parm.name AS Parameter,    
        parm.max_length, 
        parm.parameter_id 

from    sys.procedures sp

        join sys.parameters parm ON sp.object_id = parm.object_id 

where   sp.name = 'yyy_test'

order   by parm.parameter_id

수율 :

parameter           max_length  parameter_id
@col_one            -1          1
@col_two            -1          2
@col_three           2          3
@col_four            2          4
@col_five            256        5
@col_six             256        6
@col_seven           256        7

이:

select  parm.name as parameter,    
        parm.max_length, 
        parm.parameter_id,
        typ.name as data_type, 
        typ.system_type_id, 
        typ.user_type_id,
        typ.collation_name,
        typ.is_nullable 
from    sys.procedures sp

        join sys.parameters parm ON sp.object_id = parm.object_id

        join sys.types typ ON parm.system_type_id = typ.system_type_id

where   sp.name = 'yyy_test'

order   by parm.parameter_id

당신에게 이것을 제공합니다 :

parameter   max_length  parameter_id    data_type   system_type_id  user_type_id    collation_name                  is_nullable
@col_one    -1          1               nvarchar    231             231             SQL_Latin1_General_CP1_CI_AS    1
@col_one    -1          1               sysname     231             256             SQL_Latin1_General_CP1_CI_AS    0
@col_two    -1          2               nvarchar    231             231             SQL_Latin1_General_CP1_CI_AS    1
@col_two    -1          2               sysname     231             256             SQL_Latin1_General_CP1_CI_AS    0
@col_three   2          3               nvarchar    231             231             SQL_Latin1_General_CP1_CI_AS    1
@col_three   2          3               sysname     231             256             SQL_Latin1_General_CP1_CI_AS    0
@col_four    2          4               nvarchar    231             231             SQL_Latin1_General_CP1_CI_AS    1
@col_four    2          4               sysname     231             256             SQL_Latin1_General_CP1_CI_AS    0
@col_five    256        5               nvarchar    231             231             SQL_Latin1_General_CP1_CI_AS    1
@col_five    256        5               sysname     231             256             SQL_Latin1_General_CP1_CI_AS    0
@col_six     256        6               nvarchar    231             231             SQL_Latin1_General_CP1_CI_AS    1
@col_six     256        6               sysname     231             256             SQL_Latin1_General_CP1_CI_AS    0
@col_seven   256        7               nvarchar    231             231             SQL_Latin1_General_CP1_CI_AS    1
@col_seven   256        7               sysname     231             256             SQL_Latin1_General_CP1_CI_AS    0

sys.types사용자가 생성 한 사용자 정의 유형도 보유합니다 . 그렇게 create type MyInt from int하면와 함께 두 개의 행이 system_type_id = 56있습니다. 기본적으로 복제되는 또 다른 하나는 240이며 hierarchyid, geometry 및 geography의 시스템 유형입니다.
Mikael Eriksson

나는 그것을 완전히 잊었다. 그렇다면 ... sysname 으로이 물건을 쿼리하는 이상적인 방법은 무엇입니까? 그것은 '별명'이기 때문에 where typ.name<>'sysname'내가 알지 못하는 다른 종류의 결과를 얻을 수 있습니까?
gloomy.penguin

3
system_type_id 및 user_type_id에서 sys.types에 대해 조인하십시오. SQL Fiddle
Mikael Eriksson

오, 그게 내가 맨 위에 말한 것입니다. 나는 당신이 ... 그 잘못 말하는 줄 알았는데
gloomy.penguin

미안하지만 내 뜻은 아니야 sysname만이 두 열을 조인하지 않고 슬픔을 일으킬 수있을뿐만 아니라 쿼리를 망칠 수있는 다른 것들을 지적하고 싶었습니다.
Mikael Eriksson

3

아래에 사용 사례를 나열하겠습니다. 도움이 되길 바랍니다. 여기서 DB 'Students'에서 'Stud_dtls'테이블의 테이블 소유자를 찾으려고합니다. Mikael이 언급했듯이 sysname은 테이블 이름, 열 이름 및 서버 이름을 보유하는 변수가 필요한 동적 SQL을 작성해야 할 때 사용할 수 있습니다. 그의 요점을 보완하는 간단한 예를 제공하는 것을 생각했습니다.

USE Students

DECLARE @TABLE_NAME sysname

SELECT @TABLE_NAME = 'Stud_dtls'

SELECT TABLE_SCHEMA 
  FROM INFORMATION_SCHEMA.Tables
 WHERE TABLE_NAME = @TABLE_NAME

2

sysnamesp_send_dbmail"지정된받는 사람에게 전자 메일 메시지를 보내고"msdb 데이터베이스에있는 저장 프로 시저 인에 의해 사용됩니다 .

에 따르면 마이크로 소프트 ,

[ @profile_name = ] 'profile_name'  

메시지를 보낼 프로필의 이름입니다. profile_name은 sysname 유형이며 기본값은 NULL입니다. profile_name은 기존 데이터베이스 메일 프로파일의 이름이어야합니다. profile_name을 지정하지 않으면 sp_send_dbmail은 현재 사용자의 기본 개인 프로필을 사용합니다. 사용자에게 기본 개인 프로필이 없으면 sp_send_dbmail은 msdb 데이터베이스에 대한 기본 공용 프로필을 사용합니다. 사용자에게 기본 개인 프로파일이없고 데이터베이스에 대한 기본 공용 프로파일이없는 경우 @profile_name을 지정해야합니다.


1

다음과 같은 방법으로 데이터베이스를 탐색하려는 경우 다음과 같이 유용한 시스템 SP에 테이블 이름을 전달할 수 있습니다.

DECLARE @Table sysname; SET @Table = 'TableName';
EXEC sp_fkeys @Table;
EXEC sp_help @Table;

0

또 다른 사용 사례는 SQL Server 2016+ 기능을 사용할 때입니다. AT TIME ZONE

아래 문장은 GMT로 변환 된 날짜를 반환합니다

SELECT 
CONVERT(DATETIME, SWITCHOFFSET([ColumnA], DATEPART(TZOFFSET, [ColumnA] AT TIME ZONE 'GMT Standard Time')))

시간대를 변수로 전달하려면 다음과 같이 말하십시오.

SELECT 
CONVERT(DATETIME, SWITCHOFFSET([ColumnA], DATEPART(TZOFFSET, [ColumnA] AT TIME ZONE @TimeZone)))

그런 다음 해당 변수는 유형이어야합니다 sysname( varchar오류를 유발할 것이라고 선언 ).


0

제공 할 수있는 사용 사례가 있습니까?

데이터베이스 유지 보수 스크립트에서 사용하기 위해 오브젝트 이름을 저장하려는 곳. 예를 들어, 스크립트는 날짜 열이있는 특정 테이블에서 오래된 행을 제거합니다. 테이블 이름, 필터링 할 열 이름 및 보존 기간 (일)을 제공하는 테이블로 구성됩니다. 다른 스크립트는 특정 테이블을 CSV 파일로 덤프하고 다시 덤프 할 테이블을 나열하는 테이블로 구성됩니다. 이 구성 테이블은 sysname유형을 사용하여 테이블 및 열 이름을 저장할 수 있습니다 .


당신은 전혀 필요하지 않습니다. nvarchar(128) not null열을 사용하십시오 . 이름은 바로 그 이름입니다. 그것은 할 필요가 없습니다 sysname사용
파나지오티스 Kanavos

물론, 실제로는 해당 유형일 필요 nvarchar(300)조차 varchar없으며 테이블 이름에 유니 코드를 사용하지 않아도 (아무도 아무도 모르기 때문에) 작동합니다. 장점 sysname은 부분적으로 의도를 명확하게한다는 것입니다.이 열에는 개체 이름이 있습니다. 그리고 부분적으로 이전에 발생한 것처럼 개체 이름에 사용 된 데이터 형식을 변경하는 다른 버전의 MSSQL로 마이그레이션하더라도 계속 올바른 형식이됩니다.
Ed Avis

아닙니다. 에 매핑 된 다른 사용자 유형 (본질 상 별칭) 일뿐 nvarchar(128) NOT NULL입니다. 실제로 user_type_id열의 값 을 확인하여 유형을 찾는 방법 입니다. 당신 은 당신 자신의 사용자 타입을 생성하는 것보다 그 타입을 사용함으로써 더 이상 아무것도 얻지 못합니다
Panagiotis Kanavos

sysname새로운 MSSQL 버전에서 정의 가 변경되고 데이터베이스가 새로운 인스턴스로 백업 및 복원 된 경우 이전에 있었던 모든 열 sysname이 이제 잘못된 유형이고 더 이상 사용 된 유형과 일치하지 않음 을 의미합니까? 시스템 테이블에?
Ed Avis

그런 일이 발생하면 기둥에 호스가 있습니다. 256 sysname의 사용자 정의 형식입니다 . 변경할 수있는 방법이 없습니다. 새 유형을 작성하고 이전 유형을 사용한 모든 열을 새 유형으로 변경해야합니다. MS가이를 변경하기로 결정하면 그들은 줄 새로운 유형의 기존 시스템 테이블의 데이터를 마이그레이션해야합니다. 이미 알고있는 시스템 테이블에 대해이 작업을 수행 할 것으로 예상 할 수 있지만 모든 사용자 테이블은 사용자 가 마이그레이션해야합니다.usert_type_idALTER TYPE
Panagiotis Kanavos
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.