2012-05-21 29 views
3

我正在使用具有大量用户定义SQL类型的遗留数据库。我在.NET中编写了一个方法,在该方法中,我在SqlParameter对象中定义了参数。我需要用户定义类型的底层SQL类型,以便在运行时动态创建参数时正确定义参数。查找用户定义类型的SQL基类型

要做到这一点,我创建了这个过程:

(@typename sysname) 

AS 

SET NOCOUNT ON 

SELECT distinct 
st.name as UserType, 
t.precision, t.max_length, 
bt.name as BaseType 
FROM 
dbo.syscolumns c 
INNER JOIN dbo.systypes st ON st.xusertype = c.xusertype 
INNER JOIN dbo.systypes bt ON bt.xusertype = c.xtype 
inner join sys.types t on st.name = t.name 
WHERE 
st.name = 'bVendor' 

我想知道如果这是去获得底层基本类型为用户定义类型的最佳方式?

+0

这种方法看起来很合理。你有什么特别的问题吗? –

+0

我唯一的问题是在这个过程中的输入类型是sysname,它是一个奇怪的选择作为输入类型。当我传入一个字符串时它似乎工作正常,但它让我有点紧张。 –

+0

'sysname'只是'nvarchar'的别名,这会让你紧张吗? –

回答

7

你不应该使用systypes或syscolumns--它们是向后兼容的视图,并且sys.types和sys.columns是非常受欢迎的,除非你试图编写在SQL Server 2000+上工作的代码(我不' t推荐)。

要获得有关类型你已经知道的名称的信息:

SELECT name, precision, scale, max_length 
    FROM sys.types AS t 
    WHERE name = 'bVendor'; 

要获取的信息在数据库中的所有用户定义类型:

SELECT name, precision, scale, max_length 
    FROM sys.types AS t 
    WHERE is_user_defined = 1; 

要获得有关特定表格的所有类型(系统和用户定义的)的信息:

UPDATE要包含基本类型:

SELECT 
    [column] = c.name, 
    [base type] = COALESCE(bt.name, t.name), 
    [defined type] = t.name, 
    t.precision, 
    t.scale, 
    t.max_length 
FROM sys.columns AS c 
INNER JOIN sys.types AS t 
ON c.system_type_id = t.system_type_id 
AND c.user_type_id = t.user_type_id 
LEFT OUTER JOIN sys.types AS bt 
ON t.is_user_defined = 1 
AND bt.is_user_defined = 0 
AND t.system_type_id = bt.system_type_id 
AND t.user_type_id <> bt.user_type_id 
WHERE c.object_id = OBJECT_ID('dbo.your_table_name'); 

请注意,如果您使用别名类型(例如, CREATE TYPE blat FROM nvarchar(32);)。如果你真的必须使用这些(I recommend against them, also),那么加盟条款改为:

ON t.is_user_defined = 1 
AND bt.is_user_defined = 0 
AND t.system_type_id = bt.system_type_id 
AND bt.user_type_id = bt.system_type_id 
+0

感谢您的回答。我真正需要的是用户定义类型的底层SQL类型。您建议的语句中的名称列仍返回用户定义类型的名称,而不是它所表示的SQL类型。 –

+0

@AaronL。对不起,在输出中错过了。现在请尝试 –

+0

我认为这会让我足够接近我需要的东西。谢谢。然而,令我惊讶的是,没有包含用户定义类型的名称以及它们所涉及的SQL类型的属性的表。我想知道MS用什么来填充SSMS中用户定义类型的列表?该列表始​​终包含usertype及其对应的SQL类型。 –

0

要获取的信息对所有的用户定义类型在数据库中,你可以使用INFORMATION_SCHEMA.DOMAINS:

SELECT 
    DOMAIN_SCHEMA, 
    DOMAIN_NAME, 
    DATA_TYPE, 
    NUMERIC_PRECISION, 
    NUMERIC_SCALE, 
    DATETIME_PRECISION, 
    CHARACTER_MAXIMUM_LENGTH 

FROM 
    INFORMATION_SCHEMA.DOMAINS 

UPD: 以下查询返回人类可读的定义为所有用户defind类型:

SELECT 
    DOMAIN_SCHEMA + '.' + DOMAIN_NAME AS TypeName, 
    DATA_TYPE + 
     COALESCE('('+ 
      CAST(COALESCE(NUMERIC_PRECISION,DATETIME_PRECISION,CHARACTER_MAXIMUM_LENGTH) AS VARCHAR) + 
      COALESCE(',' + CAST(NUMERIC_SCALE AS VARCHAR),'') + 
     ')','') AS Definition 

    FROM 
    (
    SELECT 
     DOMAIN_SCHEMA, 
     DOMAIN_NAME, 
     DATA_TYPE, 
     CASE 
      WHEN DATA_TYPE IN ('tinyint','smallint','int','bigint') THEN NULL 
      ELSE NUMERIC_PRECISION 
     END AS NUMERIC_PRECISION, 
     NUMERIC_SCALE, 
     CASE 
      WHEN DATA_TYPE IN ('smalldatetime','datetime','date') THEN NULL 
      ELSE DATETIME_PRECISION 
     END AS DATETIME_PRECISION, 
     CHARACTER_MAXIMUM_LENGTH 

    FROM 
     INFORMATION_SCHEMA.DOMAINS 
) T 

(测试仅针对我使用M种我自己)