Answers:
sysname
是一种内置数据类型,仅限于128个Unicode字符,即IIRC,主要用于在创建脚本时存储对象名称。它的值不能是NULL
与使用基本相同 nvarchar(128) NOT NULL
编辑
就像@Jim在评论中提到的那样,我认为您真的不会有一个sysname
诚实的商业案例。它主要由Microsoft sys
在SQL Server中构建内部表和存储过程等时使用。
例如,通过执行,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数据类型用于表的列,变量和存储过程参数存储对象名称。sysname的确切定义 与标识符规则有关。因此,它在SQL Server实例之间可能会有所不同。sysname在功能上与nvarchar(128)相同,除了默认情况下sysname为NOT NULL。在早期版本的SQL Server中,sysname定义为varchar(30)。
有关sysname
允许或不允许NULL
值的一些其他信息,请参见https://stackoverflow.com/a/52290792/300863
仅仅因为它是默认值(不能为NULL)不能保证它会是默认值!
sysname
在脚本中使用前向(和向后)兼容性。
nvarchar(max)
在SP 中声明为非null,但sysname
在sys表中显示为a 。
sys.types
它nvarchar(256) not null
。请注意,系统类型ID = 231(nvarchar)。如今,它已用作TDS中的类型别名。别名的第一个ID为256,对应于sysname
。至于用法:sysname
用于信息模式。
您可以提供用例吗?
如果您需要创建一些动态sql,则适合将其用作sysname
包含表名,列名和服务器名的变量的数据类型。
就像是仅供参考。
select * from sys.types where system_type_id = 231
给你两行。
(我不确定这是什么意思,但我100%肯定它现在正在弄乱我的代码)
编辑:我想这意味着在这种情况下(我的情况),您应该由user_type_id加入,或者可能是user_type_id和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
该查询:
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,它是architectureid,geometry和geography的系统类型。
where typ.name<>'sysname'
还是会产生我不知道的其他后果?
让我在下面列出一个用例。希望能帮助到你。在这里,我试图从数据库“学生”中查找表“ Stud_dtls”的表所有者。正如Mikael所提到的,当需要创建一些动态sql时,可以使用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
sysname
由使用sp_send_dbmail
,该存储过程位于msdb数据库中,该存储过程“向指定的收件人发送电子邮件”。
根据微软的说法,
[ @profile_name = ] 'profile_name'
是从中发送消息的配置文件的名称。profile_name的类型为sysname,默认值为NULL。profile_name必须是现有数据库邮件配置文件的名称。如果未指定profile_name,则sp_send_dbmail使用当前用户的默认专用配置文件。如果用户没有默认的专用配置文件,则sp_send_dbmail使用msdb数据库的默认的公共配置文件。如果用户没有默认的私有配置文件,并且数据库没有默认的公共配置文件,则必须指定@profile_name。
另一个用例是使用SQL Server 2016+功能时 AT TIME ZONE
以下语句将返回转换为格林尼治标准时间的日期
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
将其声明为会导致错误)。
您可以提供用例吗?
您想要存储对象名称以供数据库维护脚本使用的任何位置。例如,脚本从具有日期列的某些表中清除旧行。它配置有一个表,该表提供表名,要过滤的列名以及要保留的历史天数。另一个脚本将某些表转储为CSV文件,并再次配置了一个表,该表列出了要转储的表。这些配置表可以使用该sysname
类型来存储表名和列名。
nvarchar(128) not null
列。名字就是那个名字。不必sysname
使用它
nvarchar(300)
即使varchar
在表名中不使用Unicode时,它也可以工作(因为我敢肯定,几乎没有人这样做)。的优势sysname
部分在于,它使意图更清晰:此列包含一个对象名称;并且部分原因是,即使您迁移到另一版本的MSSQL,该版本更改了用于对象名称的数据类型(如前所述),它仍将是正确的类型。
nvarchar(128) NOT NULL
。实际上,这就是查找类型的方法-通过检查user_type_id
列的值。通过使用该类型,您所获得的无非是创建自己的用户类型
sysname
在较新的MSSQL版本中更改的定义,并且数据库已备份并还原到该较新的实例中,则以前所有的列sysname
现在都将具有错误的类型,并且不再与使用的类型匹配在系统表中?
sysname
是具有usert_type_id
256 的用户定义类型。没有,ALTER TYPE
因此无法更改它。您必须创建一种新类型,并将所有使用旧类型的列更改为新类型。如果MS决定更改此设置,则必须将现有的系统表数据迁移到新类型。您可以期望他们为他们已经知道的系统表执行此操作,但是任何用户表都必须由用户迁移