简体   繁体   English

如何判断列是否属于 sysname 类型

[英]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.typesis_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM