Apa tipe data SYSNAME dalam SQL Server?

131

Untuk apa tipe data SQL Server SYSNAME? BOL mengatakan:

Tipe data sysname digunakan untuk kolom tabel, variabel, dan parameter prosedur tersimpan yang menyimpan nama objek.

tapi saya tidak begitu mengerti. Apakah ada case-use yang bisa Anda berikan?

jrara
sumber
1
Selain jawaban yang baik-baik saja di bawah, ini juga digunakan untuk menyebabkan malapetaka bagi seseorang yang mencoba untuk mendapatkan metadata kolom menggunakan sys.types, karena itu berbagi system_type_id yang sama dengan nvarchar.
StingyJack

Jawaban:

150

sysnameadalah tipe data bawaan terbatas untuk 128 karakter Unicode yang, IIRC, digunakan terutama untuk menyimpan nama objek saat membuat skrip. Nilainya tidak bisaNULL

Ini pada dasarnya sama dengan menggunakan nvarchar(128) NOT NULL

EDIT

Seperti yang disebutkan oleh @ Jim dalam komentar, saya tidak berpikir benar-benar ada kasus bisnis di mana Anda ingin sysnamejujur. Ini terutama digunakan oleh Microsoft ketika membangun systabel internal dan prosedur tersimpan dll dalam SQL Server.

Misalnya, dengan mengeksekusi Exec sp_help 'sys.tables'Anda akan melihat bahwa kolom namedidefinisikan karena sysnameini karena nilai ini sebenarnya adalah objek itu sendiri (tabel)

Saya akan terlalu khawatir tentang hal itu.

Ini juga perlu dicatat bahwa untuk orang-orang yang masih menggunakan SQL Server 6.5 dan lebih rendah (apakah masih ada orang yang menggunakannya?) Tipe bawaan sysnameadalah setara denganvarchar(30)

Dokumentasi

sysnamedidefinisikan dengan dokumentasi untuk nchardannvarchar , di bagian komentar:

sysname adalah tipe data yang ditentukan pengguna yang disediakan oleh sistem yang secara fungsional setara dengan nvarchar (128) , kecuali bahwa itu tidak dapat dibatalkan. sysname digunakan untuk referensi nama objek database.

Untuk memperjelas pernyataan di atas, secara default sysname didefinisikan karena NOT NULLtentu saja mungkin untuk mendefinisikannya sebagai nullable. Penting juga untuk dicatat bahwa definisi yang tepat dapat bervariasi antara contoh SQL Server.

Menggunakan Jenis Data Khusus

The sysName tipe data yang digunakan untuk kolom tabel, variabel, dan disimpan parameter prosedur yang nama toko objek. Definisi tepat sysname terkait dengan aturan untuk pengidentifikasi. Oleh karena itu, dapat bervariasi di antara contoh SQL Server. sysname secara fungsional sama dengan nvarchar (128) kecuali bahwa, secara default, sysname BUKAN NULL. Dalam versi SQL Server sebelumnya, sysname didefinisikan sebagai varchar (30).

Beberapa informasi lebih lanjut tentang sysnamemengizinkan atau melarang NULLnilai dapat ditemukan di sini https://stackoverflow.com/a/52290792/300863

Hanya karena itu adalah default (untuk TIDAK NULL) tidak menjamin bahwa itu akan menjadi!

pembuat kode
sumber
1
"Adakah kasing yang bisa kamu berikan?" Saya tidak berpikir Anda akan menemukan alasan bisnis yang praktis untuk digunakan. Sebagian besar digunakan secara internal dalam MS SQL karena mungkin digunakan cukup banyak dalam tabel, dll.
Jim
9
Anda akan menggunakan sysnameuntuk kompatibilitas maju (dan mundur) dalam skrip Anda.
Martin Smith
hanya dengan memasukkan 2 sen di sini: kolom yang membawa saya ke sini dinyatakan nvarchar(max)bukan nol di SP tetapi ditampilkan sebagai sysnamedalam tabel sys.
gloomy.penguin
3
@Barry Sebenarnya ... menurut sys.typesa nvarchar(256) not null. Perhatikan bahwa ID jenis sistem = 231 (nvarchar). Ini berfungsi sebagai jenis alias di TDS saat ini; ID pertama alias adalah 256, yang sesuai dengan sysname. Adapun penggunaan: sysnamedigunakan dalam skema informasi.
atlaste
2
@atlaste Panjang max_length di sys.tables adalah dalam byte. nvarchar menggunakan dua byte per karakter, itulah sebabnya didefinisikan sebagai nvarchar (128).
David Rushton
60

Adakah kasing yang bisa Anda berikan?

Jika Anda memiliki kebutuhan untuk membuat beberapa sql dinamis, maka tepat untuk digunakan sysnamesebagai tipe data untuk variabel yang menyimpan nama tabel, nama kolom dan nama server.

Mikael Eriksson
sumber
6

Sama seperti FYI ....

select * from sys.types where system_type_id = 231 memberi Anda dua baris.

(Saya tidak yakin apa artinya ini tetapi saya 100% yakin itu mengacaukan kode saya sekarang)

sunting: saya kira artinya adalah Anda harus bergabung dengan user_type_id dalam situasi ini (situasi saya) atau mungkin juga user_type_id dan th esystem_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 

Kueri ini:

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

hasil:

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

dan ini:

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

memberi Anda ini:

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
gloomy.penguin
sumber
sys.typesmemegang jenis yang ditentukan pengguna yang Anda buat juga. Jika Anda melakukannya, create type MyInt from intAnda akan memiliki dua baris system_type_id = 56. Lain yang digandakan secara default adalah 240 yang merupakan tipe sistem untuk hierarki, geometri dan geografi.
Mikael Eriksson
Saya benar-benar lupa tentang itu. Jadi ... apa cara ideal untuk menanyakan hal-hal ini dengan sysname di sana? karena ini adalah 'alias' yang bisa saya lakukan where typ.name<>'sysname'atau apakah ada konsekuensi lain yang tidak saya sadari?
gloomy.penguin
3
Bergabunglah melawan sys.types di system_type_id dan user_type_id. SQL Fiddle
Mikael Eriksson
oh, itulah yang saya katakan di bagian paling atas. Saya pikir Anda mengatakan itu salah ...
gloomy.penguin
Maaf soal itu, bukan maksud saya. Hanya ingin menunjukkan beberapa hal lain yang dapat mengacaukan kueri Anda, tidak hanya sysname yang dapat menyebabkan Anda bersedih tanpa bergabung di kedua kolom.
Mikael Eriksson
3

Biarkan saya daftar kasus penggunaan di bawah ini. Semoga ini bisa membantu. Di sini saya mencoba untuk menemukan Pemilik Tabel dari Tabel 'Stud_dtls' dari DB 'Students'. Seperti yang disebutkan Mikael, sysname dapat digunakan ketika ada kebutuhan untuk membuat beberapa sql dinamis yang memerlukan variabel yang menyimpan nama tabel, nama kolom dan nama server. Hanya memikirkan memberikan contoh sederhana untuk melengkapi maksudnya.

USE Students

DECLARE @TABLE_NAME sysname

SELECT @TABLE_NAME = 'Stud_dtls'

SELECT TABLE_SCHEMA 
  FROM INFORMATION_SCHEMA.Tables
 WHERE TABLE_NAME = @TABLE_NAME
OK
sumber
2

sysnamedigunakan oleh sp_send_dbmail, prosedur tersimpan yang "Mengirim pesan email ke penerima yang ditentukan" dan terletak di database msdb.

Menurut Microsoft ,

[ @profile_name = ] 'profile_name'  

Adalah nama profil untuk mengirim pesan. Profil_name bertipe sysname, dengan default NULL. Profil_name haruslah nama profil Mail Database yang ada. Ketika tidak ada profile_name yang ditentukan, sp_send_dbmail menggunakan profil pribadi default untuk pengguna saat ini. Jika pengguna tidak memiliki profil pribadi default, sp_send_dbmail menggunakan profil publik default untuk database msdb. Jika pengguna tidak memiliki profil pribadi default dan tidak ada profil publik default untuk database, @profile_name harus ditentukan.

BermanfaatBee
sumber
1

FWIW, Anda dapat memberikan nama tabel ke sistem SP yang berguna seperti ini, jika Anda ingin menjelajahi basis data seperti itu:

DECLARE @Table sysname; SET @Table = 'TableName';
EXEC sp_fkeys @Table;
EXEC sp_help @Table;
Ajs Jsy
sumber
0

Kasus penggunaan lain adalah ketika menggunakan fungsionalitas SQL Server 2016+ AT TIME ZONE

Pernyataan di bawah ini akan mengembalikan tanggal yang dikonversi ke GMT

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

Jika Anda ingin melewati zona waktu sebagai variabel, katakan:

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

maka variabel tersebut harus bertipe sysname(menyatakannya sebagai varcharakan menyebabkan kesalahan).

d219
sumber
0

Adakah kasing yang bisa Anda berikan?

Di mana pun Anda ingin menyimpan nama objek untuk digunakan oleh skrip pemeliharaan basis data. Misalnya, skrip membersihkan baris lama dari tabel tertentu yang memiliki kolom tanggal. Ini dikonfigurasi dengan tabel yang memberikan nama tabel, nama kolom untuk difilter, dan berapa hari riwayat disimpan. Skrip lain membuang tabel tertentu ke file CSV, dan sekali lagi dikonfigurasi dengan tabel yang mencantumkan tabel untuk dibuang. Tabel konfigurasi ini dapat menggunakan sysnametipe untuk menyimpan nama tabel dan kolom.

Ed Avis
sumber
Anda tidak membutuhkan itu sama sekali. Cukup gunakan nvarchar(128) not nullkolom. Namanya hanya itu, nama. Tidak sysnameharus digunakan
Panagiotis Kanavos
Tentu, dan pada kenyataannya itu bahkan tidak harus dari jenis itu, nvarchar(300)akan berfungsi juga atau bahkan hanya varcharjika Anda tidak menggunakan Unicode dalam nama tabel (karena saya yakin hampir tidak ada yang melakukannya). Keuntungannya sysnameadalah sebagian hal itu membuat niat menjadi lebih jelas: kolom ini berisi nama objek; dan sebagian bahwa bahkan jika Anda bermigrasi ke versi MSSQL yang berbeda yang mengubah tipe data yang digunakan untuk nama objek (seperti yang telah terjadi sebelumnya), itu akan terus menjadi tipe yang tepat.
Ed Avis
Tidak, tidak. Itu hanya tipe pengguna lain (dasarnya alias) yang dipetakan nvarchar(128) NOT NULL. Bahkan, itulah cara Anda dapat menemukan tipe - dengan memeriksa nilai user_type_idkolom. Anda tidak mendapatkan apa-apa lagi dengan menggunakan tipe itu, daripada membuat tipe pengguna Anda sendiri
Panagiotis Kanavos
Maksud Anda jika definisi sysnamediubah dalam versi MSSQL yang lebih baru, dan database didukung dan dikembalikan ke contoh yang lebih baru, semua kolom yang sebelumnya sysnameakan sekarang menjadi tipe yang salah dan tidak lagi cocok dengan jenis yang digunakan dalam tabel sistem?
Ed Avis
Tidak bisa, atau lebih buruk, jika itu pernah terjadi, kolom Anda disembunyikan. sysnameadalah tipe yang ditentukan pengguna dengan usert_type_id256. Tidak ada ALTER TYPEsehingga tidak ada cara untuk mengubahnya. Anda harus membuat tipe baru dan mengubah semua kolom yang menggunakan tipe lama ke yang baru. Jika MS pernah memutuskan untuk mengubah ini, mereka harus memigrasi data tabel sistem yang ada ke tipe baru. Anda dapat mengharapkan mereka melakukan ini untuk tabel sistem yang sudah mereka ketahui, tetapi tabel pengguna apa pun harus dimigrasikan oleh pengguna
Panagiotis Kanavos