[英]How to tell whether a column is of sysname type
It's a common question how to find the columns in a table by querying the system columns.如何通过查询系统列来查找表中的列是一个常见问题。 For example SQL server query to get the list of columns in a table along with Data types, NOT NULL, and PRIMARY KEY constraints gives a query which works in most cases.例如SQL 服务器查询以获取表中的列列表以及数据类型,NOT NULL 和 PRIMARY KEY 约束提供了在大多数情况下都有效的查询。 However, a column of type sysname
is returned as plain nvarchar
.但是,类型为sysname
的列作为普通nvarchar
返回。 In Management Studio (SSMS) scripting out a table definition will correctly give the sysname
type.在 Management Studio (SSMS) 中编写表定义脚本将正确地给出sysname
类型。 And so will sp_columns
. sp_columns
。 But how can I find whether a column is of sysname
type using an SQL query against the system tables?但是,如何使用针对系统表的 SQL 查询来查找列是否属于sysname
类型? (I don't want to run sp_columns
separately for each table.) (我不想为每个表单独运行sp_columns
。)
In case you are wondering what the sysname
type is to start with, What is SYSNAME data type in SQL Server?如果您想知道从什么sysname
类型开始, SQL Server 中的 SYSNAME 数据类型是什么? gives some info.提供一些信息。
To give more detail:提供更多细节:
create view some_table_names as select name from sys.tables
Then running然后运行
sp_columns 'some_table_names'
reports type_name=sysname
.报告type_name=sysname
。 But a simple query against sys.columns gives just varchar
:但是对 sys.columns 的简单查询只给出varchar
:
select type_name(c.system_type_id)
from sys.objects t
join sys.columns c
on t.object_id = c.object_id
where t.name = 'some_table_names'
I had a look at the definition of sp_columns
to see if I could do the same thing.我查看了sp_columns
的定义,看看我是否可以做同样的事情。 It looks up the column details in a system table sys.spt_columns_odbc_view
.它在系统表sys.spt_columns_odbc_view
中查找列详细信息。 But this is apparently some top secret internal table that can only be queried from a direct administrator connection (DAC) or from SSMS.但这显然是一些绝密内部表,只能从直接管理员连接 (DAC) 或 SSMS 中查询。 (See What is spt_columns_odbc_view and why is it not accessible? ) The sp_columns
proc manages to query this view even though I am not running it from Management Studio or over a DAC. (请参阅什么是 spt_columns_odbc_view 以及为什么它无法访问? )即使我没有从 Management Studio 或通过 DAC 运行sp_columns
proc,它也会设法查询此视图。 But I don't know how to repeat that trick in my own code.但我不知道如何在我自己的代码中重复这个技巧。
Is there some other way to tell whether a column is of sysname
type?是否有其他方法可以判断列是否为sysname
类型?
First of all, there's no valid case for storing data as sysname
, even for maintenance scripts.首先,没有将数据存储为sysname
的有效案例,即使对于维护脚本也是如此。 For a script you want the actual name of a table or column, so storing it in an nvarchar(128)
field is perfectly fine.对于脚本,您需要表或列的实际名称,因此将其存储在nvarchar(128)
字段中非常好。
The system itself treats sysname
as a user type in the sys.types
table.系统本身将sysname
视为sys.types
表中的用户类型。 If you check the record, you'll see that the database itself tells you this is a nvarchar
.如果您检查记录,您会看到数据库本身告诉您这是一个nvarchar
。 If you want to return that alias name, join the sys.columns.user_type_id
column with types.user_type_id
, eg:如果要返回该别名,请使用types.user_type_id
加入sys.columns.user_type_id
列,例如:
select object_name(object_id),
types.name,
*
from sys.columns
inner join sys.types on types.user_type_id =sys.columns.user_type_id
where columns.user_type_id=256
or just要不就
select object_name(object_id),
TYPE_NAME(user_type_id),
*
from sys.columns
where user_type_id=256
UPDATE更新
I just checked the type's record on a server where I databases with different collations and noticed that the collation changes to match the database's.我刚刚检查了服务器上的类型记录,在该服务器上我使用不同的排序规则进行数据库化,并注意到排序规则更改为与数据库匹配。 So even on the same server, using that alias can lead to collation issues因此,即使在同一台服务器上,使用该别名也会导致排序问题
The sys.types
catalog view exposes data types that can be specified in DDL. sys.types
目录视图公开了可以在 DDL 中指定的数据类型。 You can join to this view on user_type_id
to identify column type.您可以在user_type_id
上加入此视图以识别列类型。 As you can see from this query, sysname
is not an internal secret type.从这个查询中可以看出, sysname
不是内部机密类型。
SELECT c.Name AS ColumnName, ty.name AS TypeName, c.max_length AS ColumnLengthBytes
FROM sys.objects t
JOIN sys.columns c ON t.object_id = c.object_id
JOIN sys.types ty ON c.user_type_id = ty.user_type_id
WHERE t.name = N'test_table';
sysname
is similar to a user-defined type. sysname
类似于用户定义的类型。 It differs from a UDT created with CREATE TYPE
in that the is_user_defined
column of sys.types
will be zero instead of one since it's defined by SQL Server rather than a user.它与使用CREATE TYPE
创建的 UDT 不同之处在于sys.types
的is_user_defined
列将为零而不是一,因为它是由 SQL 服务器而不是用户定义的。
One can also join on system_type_id
to also return both the user and base system type.还可以加入system_type_id
以同时返回用户和基本系统类型。
SELECT c.Name AS ColumnName, ty.name AS TypeName, c.max_length AS ColumnLengthBytes
FROM sys.objects t
JOIN sys.columns c ON t.object_id = c.object_id
JOIN sys.types ty ON ty.system_type_id = c.system_type_id
WHERE t.name = N'test_table';
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.