web-dev-qa-db-fra.com

Quel est le type de données SYSNAME dans SQL Server?

À quoi sert le type de données SQL Server SYSNAME? BOL dit:

Le type de données sysname est utilisé pour les colonnes de table, les variables et les paramètres de procédure stockée qui stockent les noms d'objet.

mais je ne comprends pas vraiment ça. Y a-t-il un cas d'utilisation que vous pouvez fournir?

109
jrara

sysname est un type de données intégré limité à 128 caractères Unicode qui, IIRC, sert principalement à stocker les noms d'objets lors de la création de scripts. Sa valeur ne peut pas être NULL

C'est fondamentalement la même chose que d'utiliser nvarchar(128) NOT NULL

[~ # ~] éditer [~ # ~]

Comme mentionné par @Jim dans les commentaires, je ne pense pas qu'il y ait une analyse de rentabilité dans laquelle vous utiliseriez sysname pour être honnête. Il est principalement utilisé par Microsoft lors de la construction des tables internes sys et des procédures stockées, etc., dans SQL Server.

Par exemple, en exécutant Exec sp_help 'sys.tables', Vous verrez que la colonne name est définie comme étant sysname car sa valeur est en fait un objet en soi (une table).

Je m'inquiéterais trop à ce sujet.

Il est également intéressant de noter que pour les personnes utilisant encore SQL Server 6.5 et versions antérieures (y a-t-il encore des personnes qui l'utilisent?), Le type intégré de sysname est l'équivalent de varchar(30)

Documentation

sysname est défini avec la documentation de nchar et nvarchar, dans la section remarques:

sysname est un type de données défini par l'utilisateur fourni par le système et fonctionnellement équivalent à nvarchar (128) , sauf que ce n'est pas nul. sysname est utilisé pour référencer les noms d'objet de base de données.

Pour clarifier les remarques ci-dessus, par default sysname est défini comme NOT NULL Il est certainement possible de définissez-le comme nullable. Il est également important de noter que la définition exacte peut varier entre les instances de SQL Server.

tilisation de types de données spéciaux

Le type de données sysname est utilisé pour les colonnes de table, les variables et les paramètres de procédure stockée qui stockent les noms d'objet. La définition exacte de sysname est liée aux règles relatives aux identificateurs. Par conséquent, il peut varier entre les instances de SQL Server. sysname est fonctionnellement identique à nvarchar (128) sauf que, par défaut, sysname n'est PAS NULL. Dans les versions antérieures de SQL Server, sysname est défini par varchar (30).

126
codingbadger

Y a-t-il un cas d'utilisation que vous pouvez fournir?

Si vous avez besoin de créer sql dynamique , il convient d'utiliser sysname comme type de données pour les variables contenant les noms de table, les noms de colonne et les noms de serveur.

55
Mikael Eriksson

Laissez-moi énumérer un cas d'utilisation ci-dessous. J'espère que ça aide. Ici, j'essaie de trouver le propriétaire de la table 'Stud_dtls' à partir de la base de données 'Students'. Comme Mikael l'a mentionné, sysname peut être utilisé lorsqu'il est nécessaire de créer un SQL dynamique qui nécessite des variables contenant des noms de table, des noms de colonne et des noms de serveur. Je viens de penser à donner un exemple simple pour compléter son propos.

USE Students

DECLARE @TABLE_NAME sysname

SELECT @TABLE_NAME = 'Stud_dtls'

SELECT TABLE_SCHEMA 
  FROM INFORMATION_SCHEMA.Tables
 WHERE TABLE_NAME = @TABLE_NAME
3
aok

Juste comme un FYI ....

select * from sys.types where system_type_id = 231 vous donne deux lignes.

(Je ne sais pas encore ce que cela signifie, mais je suis sûr à 100% que ça gâche mon code pour le moment.)

edit: Je suppose que cela signifie que vous devez rejoindre le user_type_id dans cette situation (ma situation) ou éventuellement les deux, user_type_id et 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 

Cette requête:

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

rendements:

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

et ceci:

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

vous donne ceci:

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
3
gloomy.penguin

FWIW, vous pouvez donner un nom de table à des SP utiles tels que celui-ci, si vous souhaitez explorer une base de données de cette façon:

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

sysname est utilisé par sp_send_dbmail, procédure stockée qui "Envoie un message électronique aux destinataires spécifiés" et située dans la base de données msdb.

Selon Microsoft ,

[ @profile_name = ] 'profile_name'  

Est le nom du profil à partir duquel envoyer le message. Nom_profil est de type sysname, avec la valeur par défaut NULL. Nom_profil doit être le nom d'un profil de messagerie de base de données existant. Si aucun nom de profil n'est spécifié, sp_send_dbmail utilise le profil privé par défaut pour l'utilisateur actuel. Si l'utilisateur ne dispose pas d'un profil privé par défaut, sp_send_dbmail utilise le profil public par défaut pour la base de données msdb. Si l'utilisateur ne possède pas de profil privé par défaut et qu'il n'existe pas de profil public par défaut pour la base de données, vous devez spécifier @profile_name.

1
usefulBee

Un autre cas d'utilisation concerne l'utilisation de la fonctionnalité SQL Server 2016+ de AT TIME ZONE

La déclaration ci-dessous renverra une date convertie en GMT

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

Si vous voulez passer le fuseau horaire en tant que variable, dites:

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

alors cette variable doit être du type sysname (la déclarer comme varchar provoquera une erreur).

0
d219