SQL Server'da SYSNAME veri türü nedir?


131

SQL Server SYSNAME veri türü ne içindir? BOL diyor ki:

Sysname veri türü, tablo sütunları, değişkenler ve nesne adlarını depolayan saklı yordam parametreleri için kullanılır.

ama bunu gerçekten anlamıyorum. Sağlayabileceğiniz bir kullanım durumu var mı?


1
Aşağıdaki bu iyi cevaplara ek olarak, sys.types kullanarak sütun meta verilerini almaya çalışan biri için hasara neden olmak için de kullanılır, çünkü nvarchar ile aynı system_type_id öğesini paylaşır.
StingyJack

Yanıtlar:


150

sysname128 Unicode karakterle sınırlı yerleşik bir veri türüdür ve IIRC, komut dosyaları oluştururken öncelikle nesne adlarını depolamak için kullanılır. Değeri olamazNULL

Temelde kullanmakla aynıdır nvarchar(128) NOT NULL

DÜZENLE

@ Jim'in yorumlarda bahsettiği gibi, sysnamedürüst olmak için kullanacağınız bir iş vakası olduğunu sanmıyorum . Genelde Microsoft tarafından dahili systablolar ve depolanmış prosedürler vb. Oluşturulurken SQL Server içinde kullanılır.

Örneğin, çalıştırdığınızda Exec sp_help 'sys.tables', sütunun namebu şekilde tanımlandığını göreceksiniz sysnameçünkü bunun değeri aslında kendi içinde bir nesne (bir tablo)

Bunun için çok endişelenirdim.

Ayrıca, hala SQL Server 6.5 ve altını kullanan kişiler için (hala onu kullanan insanlar var mı?) Yerleşik türünün sysnameeşdeğer olduğunu belirtmek gerekir .varchar(30)

belgeleme

sysnameaçıklamalar bölümünde ncharvenvarchar için dokümantasyon ile tanımlanır :

sysname , nullable olmaması dışında , işlevsel olarak nvarchar (128) 'e eşdeğer olan, sistem tarafından sağlanan kullanıcı tanımlı bir veri türüdür . sysname , veritabanı nesne adlarına başvurmak için kullanılır.

Yukarıdaki açıklamaları açıklığa kavuşturmak için, varsayılan olarak sysname tanımlanır, çünkü NOT NULLonu null yapılabilir olarak tanımlamak kesinlikle mümkündür. Kesin tanımın SQL Server örnekleri arasında farklılık gösterebileceğine dikkat etmek de önemlidir.

Özel Veri Türlerini Kullanma

Sysname veri tipi tablo sütunları, parametreler için kullanılan ve bu depo nesne adları yordam parametreleri kaydedilir. Sysname'nin tam tanımı, tanımlayıcılar için kurallarla ilgilidir. Bu nedenle, SQL Server örnekleri arasında değişiklik gösterebilir. sysname , işlevsel olarak nvarchar (128) ile aynıdır, tek fark, varsayılan olarak, sysname NULL DEĞİLDİR. SQL Server'ın önceki sürümlerinde sysname , varchar (30) olarak tanımlanır.

Değerlere sysnameizin verme veya vermeyi reddetme hakkında daha fazla bilgi NULLburada https://stackoverflow.com/a/52290792/300863 bulunabilir.

Öntanımlı olması (BOŞ DEĞİLDİR) olacağını garanti etmez!


1
"Sağlayabileceğiniz bir kullanım durumu var mı?" Kullanmak için pratik bir iş nedeni bulacağınızı sanmıyorum. Çoğunlukla MS SQL'de dahili olarak kullanılır, çünkü muhtemelen tablolarda vb. Oldukça kullanılır.
Jim

9
Sen kullanırsınız sysnamescriptlerinizdeki ileri (ve geri) uyumluluk için.
Martin Smith

Buraya sadece 2 sent koyarsak: beni buraya getiren sütunlar nvarchar(max)SP'de boş olarak ilan edildi, ancak sysnamesys tablolarında a olarak gösteriliyorlar .
gloomy.penguin

3
@Barry Aslında ... göre sys.typesbu bir var nvarchar(256) not null. Sistem türü kimliğinin 231 (nvarchar) olduğuna dikkat edin. Günümüzde TDS'de bir tür takma adı olarak çalışır; bir diğer adın ilk kimliği 256'dır ve buna karşılık gelir sysname. Kullanım gelince: sysnamebilgi şemalarında kullanılır.
atlaste

2
@atlaste sys.tables'daki max_length uzunluğu bayt cinsindendir. nvarchar karakter başına iki bayt kullanır, bu yüzden nvarchar (128) olarak tanımlanır.
David Rushton

60

Sağlayabileceğiniz kullanım durumu var mı?

Dinamik bir sql oluşturmaya ihtiyacınız varsa, sysnametablo adlarını, sütun adlarını ve sunucu adlarını tutan değişkenler için veri türü olarak kullanmak uygundur .


6

Tıpkı bir FYI gibi ...

select * from sys.types where system_type_id = 231 size iki sıra verir.

(Bunun ne anlama geldiğinden henüz emin değilim, ancak şu anda kodumu bozduğundan% 100 eminim)

düzenleme: sanırım bunun anlamı, bu durumda (benim durumumda) user_type_id veya muhtemelen hem user_type_id hem de esystem_type_id ile katılmanız gerektiğidir.

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 

Bu sorgu:

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

verim:

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

ve bu:

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

size şunu verir:

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.typesoluşturduğunuz kullanıcı tanımlı türleri de tutar . Eğer yaparsanız create type MyInt from int, iki satırınız olacak system_type_id = 56. Varsayılan olarak çoğaltılan bir diğeri, hiyerarşi, geometri ve coğrafya için sistem türü olan 240'tır.
Mikael Eriksson

Bunu tamamen unutmuşum. Öyleyse ... içinde sysname olan bu şeyleri sorgulamanın ideal yolu nedir? bir 'takma ad' olduğu için bunu yapabilir miyim yoksa where typ.name<>'sysname'bunun farkında olmadığım başka bir sonucu olur mu?
gloomy.penguin

3
Hem system_type_id hem de user_type_id'deki sys.types'e karşı katılın. SQL Fiddle
Mikael Eriksson

oh, en tepede de öyle dedim. Bunun yanlış olduğunu söylediğini sanıyordum ...
kasvetli penguen

Bunun için üzgünüm, benim kastettiğim değil. Sorgunuzu bozabilecek diğer bazı şeylere dikkat çekmek istedim, yalnızca sysname her iki sütuna da katılmadan kederlenmenize neden olmaz.
Mikael Eriksson

3

Aşağıda bir kullanım örneği listeleyeyim. Umarım yardımcı olur. Burada "Stud_dtls" tablosunun Masa Sahibini DB "Students" den bulmaya çalışıyorum. Mikael'in bahsettiği gibi, sysname, tablo isimleri, sütun isimleri ve sunucu isimlerini tutan değişkenlere ihtiyaç duyan bazı dinamik sql'lerin oluşturulması gerektiğinde kullanılabilir. Söylediği noktayı tamamlamak için basit bir örnek vermeyi düşündüm.

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"Belirtilen alıcılara e-posta iletisi gönderen" ve msdb veritabanında bulunan bir saklı yordam tarafından kullanılır .

Microsoft'a göre ,

[ @profile_name = ] 'profile_name'  

Mesajın gönderileceği profilin adıdır. Profile_name, varsayılan NULL olmak üzere sysname türündedir. Profil_adı, mevcut bir Veritabanı Posta profilinin adı olmalıdır. Profil_adı belirtilmediğinde, sp_send_dbmail geçerli kullanıcı için varsayılan özel profili kullanır. Kullanıcının varsayılan bir özel profili yoksa, sp_send_dbmail msdb veritabanı için varsayılan genel profili kullanır. Kullanıcının varsayılan bir özel profili yoksa ve veritabanı için varsayılan bir genel profil yoksa, @ profil_adı belirtilmelidir.


1

FWIW, bir veritabanını bu şekilde keşfetmek isterseniz, yararlı sistem SP'lerine bir tablo adı iletebilirsiniz:

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

0

Başka bir kullanım durumu, SQL Server 2016+ işlevselliğini kullanırken AT TIME ZONE

Aşağıdaki ifade GMT'ye dönüştürülmüş bir tarihi döndürecektir

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

Saat dilimini değişken olarak geçirmek istiyorsanız şunu söyleyin:

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

o zaman bu değişkenin türde olması gerekir ( bir hataya neden olacağı şeklinde sysnamebildirmek varchar).


0

Sağlayabileceğiniz kullanım durumu var mı?

Veritabanı bakım komut dosyaları tarafından kullanılmak üzere bir nesne adını depolamak istediğiniz her yerde. Örneğin, bir komut dosyası, tarih sütunu olan belirli tablolardan eski satırları temizler. Tablo adı, filtre uygulanacak sütun adı ve kaç günlük geçmiş tutulacağını belirten bir tabloyla yapılandırılmıştır. Başka bir komut dosyası, belirli tabloları CSV dosyalarına döker ve yine dökümü yapılacak tabloları listeleyen bir tabloyla yapılandırılır. Bu yapılandırma tabloları, sysnametablo ve sütun adlarını depolamak için türü kullanabilir .


Buna hiç ihtiyacın yok. Sadece bir nvarchar(128) not nullsütun kullanın . İsim sadece bu, bir isim. Bu olmak zorunda değildir sysnamekullanılacak
Panagiotis Kanavos

Elbette ve aslında bu türden olması bile gerekmiyor, nvarchar(300)hatta varchartablo adlarında Unicode kullanmasanız bile (neredeyse hiç kimsenin kullanmadığından eminim) işe yarayacaktır . Avantajı sysnamekısmen niyeti daha net hale getirmesidir: bu sütun bir nesne adını tutar; ve kısmen, nesne adları için kullanılan veri türünü değiştiren farklı bir MSSQL sürümüne geçseniz bile (daha önce olduğu gibi), doğru tür olmaya devam edecektir.
Ed Avis

Hayır değil. Eşlenen başka bir kullanıcı türü (esasen bir takma ad) nvarchar(128) NOT NULL. Aslında, türü bu şekilde bulabilirsiniz - user_type_idsütunun değerini kontrol ederek . Bu türü kullanarak, kendi kullanıcı türünüzü oluşturarak elde edeceğinizden daha fazla bir şey kazanamazsınız
Panagiotis Kanavos

Daha sysnameyeni bir MSSQL sürümünde tanımı değiştirildiyse ve veritabanı yedeklenip bu yeni örneğe geri yüklendiyse, daha önce bulunan tüm sütunların sysnameartık yanlış türde olacağını ve artık kullanılan türle eşleşmeyeceğini mi söylüyorsunuz? sistem tablolarında?
Ed Avis

Olmaz ya da daha kötüsü, eğer böyle bir şey olursa, sütununuz ıslanır. 256 sysnameile kullanıcı tanımlı bir türdür. Bu yüzden değiştirmenin bir yolu yoktur. Yeni bir tür oluşturmanız ve eski türü kullanan tüm sütunları yenisiyle değiştirmeniz gerekir. MS bunu değiştirmeye karar verirse , mevcut sistem tablosu verilerini yeni türe geçirmek zorunda kalacaktı . Bunu zaten bildikleri sistem tabloları için yapmalarını bekleyebilirsiniz, ancak tüm kullanıcı tablolarının kullanıcılar tarafından usert_type_idALTER TYPE
taşınması gerekir
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.