sysname
是一种内置数据类型,仅限于128个Unicode字符,并且通常用于在创建脚本时存储对象名称。它的值不能为NULL
基本上与使用nvarchar(128) NOT NULL
相同
编辑
正如评论中@Jim提到的那样,说实话我认为没有真正的商业案例需要使用sysname
。它主要由Microsoft在构建SQL Server内部的sys
表和存储过程等时使用。
例如,通过执行Exec sp_help 'sys.tables'
,你会发现列name
被定义为sysname
,这是因为此值实际上是一个对象本身(一个表)
我不会太担心它。
还值得注意的是,对于那些仍在使用SQL Server 6.5及以下版本(还有人在使用吗?),内置类型sysname
等同于varchar(30)
文档
sysname
在nchar
和nvarchar
的文档中定义,在备注部分:
sysname是一种系统提供的用户定义数据类型,与nvarchar(128)在功能上相同,不同之处在于它不可为空。 sysname用于引用数据库对象名称。
为了澄清上述备注,sysname默认情况下被定义为NOT NULL
,当然可以将其定义为可空。此外,确切的定义可能因SQL Server实例而异。
sysname
数据类型用于存储对象名称的表列、变量和存储过程参数。其确切定义与标识符的规则有关,因此在 SQL Server 实例之间可能会有所不同。sysname
与nvarchar(128)
在功能上是相同的,但默认情况下sysname
是 NOT NULL 的。在早期版本的 SQL Server 中,sysname
被定义为 varchar(30)。
有关sysname
允许还是禁止NULL
值的更多信息,请参见https://stackoverflow.com/a/52290792/300863
仅仅因为它是默认值(NOT NULL),也并不能保证它就是!
nvarchar(max)
非空,但在系统表中显示为 sysname
。 - gloomy.penguinsys.types
中的信息,它是一个 nvarchar(256) not null
。请注意,系统类型ID = 231(nvarchar)。现在它在 TDS 中作为类型别名使用;类型别名的第一个ID是256,对应于 sysname
。至于用法:sysname
用于信息模式。 - atlaste提醒一下...
select * from sys.types where system_type_id = 231
会返回两行。
(我不确定这是什么意思,但我百分之百确定它正在干扰我的代码)
编辑: 我想它的意思是在这种情况下(我的情况)你应该通过用户类型ID进行连接,或者可能是用户类型ID和系统类型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,它是层次结构、几何和地理系统类型的系统类型。 - Mikael Erikssonwhere typ.name <> 'sysname'
吗?或者这会产生我不知道的其他后果吗? - gloomy.penguin让我列举一个用例。希望这可以帮助您。在这里,我正在尝试查找DB“学生”中表“Stud_dtls”的表所有者。正如Mikael所提到的那样,当需要创建一些动态SQL来保存表名、列名和服务器名的变量时,可以使用sysname。只是想提供一个简单的示例来补充他的观点。
USE Students
DECLARE @TABLE_NAME sysname
SELECT @TABLE_NAME = 'Stud_dtls'
SELECT TABLE_SCHEMA
FROM INFORMATION_SCHEMA.Tables
WHERE TABLE_NAME = @TABLE_NAME
sysname
是由 sp_send_dbmail
使用的,它是一个存储过程,用于“向指定的收件人发送电子邮件消息”,并位于 msdb 数据库中。
根据 Microsoft 的说法,
[ @profile_name = ] 'profile_name'
Is the name of the profile to send the message from. The profile_name is of type sysname, with a default of NULL. The profile_name must be the name of an existing Database Mail profile. When no profile_name is specified, sp_send_dbmail uses the default private profile for the current user. If the user does not have a default private profile, sp_send_dbmail uses the default public profile for the msdb database. If the user does not have a default private profile and there is no default public profile for the database, @profile_name must be specified.
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
将会导致错误)。
顺带一提,如果您希望以这种方式探索数据库,可以将表名传递给有用的系统SP(存储过程):
DECLARE @Table sysname; SET @Table = 'TableName';
EXEC sp_fkeys @Table;
EXEC sp_help @Table;
sysname
类型来存储表和列名。nvarchar(128) not null
列即可。名称只是名称,它不必是 sysname
才能使用。 - Panagiotis Kanavosnvarchar(300)
也可以,或者如果您在表名中不使用Unicode,甚至只需使用varchar
(因为我几乎确定没有人这样做)。 sysname
的优点部分在于它使意图更清晰:此列保存对象名称;部分在于即使您迁移到使用不同数据类型的MSSQL的不同版本(如以前发生过的情况),它仍将是正确的类型。 - Ed Avissysname
是一个用户定义类型,其usert_type_id
为256。没有ALTER TYPE
,因此无法更改它。您必须创建一个新类型,并将使用旧类型的所有列更改为新类型。如果微软决定更改此内容,他们必须将现有系统表数据迁移到新类型。您可以期望他们为已知的系统表执行此操作,但任何用户表都必须由用户迁移。 - Panagiotis Kanavossysname
UDT。 - Panagiotis Kanavos