答案 0 :(得分:122)
sysname
是一种内置数据类型,限制为128个Unicode字符,IIRC主要用于在创建脚本时存储对象名称。其值不能为NULL
它与使用nvarchar(128) NOT NULL
修改强>
正如@Jim在评论中提到的那样,我认为确实存在一个商业案例,你要诚实地使用sysname
。它主要由Microsoft在SQL Server中构建内部sys
表和存储过程等时使用。
例如,通过执行Exec sp_help 'sys.tables'
,您会看到列name
被定义为sysname
这是因为它的值实际上是一个对象本身(一个表)< / p>
我会太担心它。
同样值得注意的是,对于那些仍在使用SQL Server 6.5及更低版本的用户(仍有人使用它吗?)内置类型的sysname
相当于varchar(30)
<强>文档强>
sysname
在 nchar
and 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)。
答案 1 :(得分:53)
您可以提供用例吗?
如果您需要创建一些dynamic sql,则使用sysname
作为包含表名,列名和服务器名的变量的数据类型是合适的。
答案 2 :(得分:3)
就像一个FYI ......
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
答案 3 :(得分:3)
让我列出下面的一个用例。希望能帮助到你。在这里,我试图从数据库'学生'中找到表'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
答案 4 :(得分:1)
FWIW,您可以将表名称传递给有用的系统SP,如果您希望以这种方式探索数据库:
DECLARE @Table sysname; SET @Table = 'TableName';
EXEC sp_fkeys @Table;
EXEC sp_help @Table;
答案 5 :(得分:1)
sysname
使用 sp_send_dbmail
,这是一个存储过程,&#34;向指定的收件人发送电子邮件&#34;并位于msdb数据库中。
根据Microsoft,
[ @profile_name = ] 'profile_name'
是要从中发送邮件的配置文件的名称。 profile_name的类型为sysname,带有 默认值为NULL。 profile_name必须是现有名称 Database Mail配置文件。如果未指定profile_name, sp_send_dbmail使用当前用户的默认私有配置文件。 如果用户没有默认的私有配置文件sp_send_dbmail 使用msdb数据库的默认公用配置文件。如果是用户 没有默认的私人个人资料,也没有默认公开 必须指定@profile_name的数据库配置文件。
答案 6 :(得分:0)
另一个用例是使用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
会导致错误)。
答案 7 :(得分:0)
您可以提供用例吗?
要存储对象名称以供数据库维护脚本使用的任何位置。例如,脚本从具有日期列的某些表中清除旧行。它配置有一个表,该表提供表名,要过滤的列名以及要保留的历史天数。另一个脚本将某些表转储为CSV文件,并再次配置了一个表,该表列出了要转储的表。这些配置表可以使用sysname
类型来存储表名和列名。