如何知道触发器中字段的数据类型?

时间:2013-12-03 15:31:50

标签: sql-server triggers

我如何知道触发器内字段的数据类型。我可以在插入后获取字段名称及其在触发器内的值,如下所示:

DECLARE @AfterInserted XML


     SELECT @AfterInserted = (
        SELECT *
        FROM INSERTED
        WHERE User_Key = User_Key
        FOR XML RAW, ROOT
    );

    CREATE TABLE #XML(
    FieldName   nvarchar(250),
    Value       nvarchar(250));


    Insert Into #XML(FieldName, Value)
      select T.N.value('local-name(.)', 'nvarchar(100)'),
             T.N.value('.', 'nvarchar(250)')
      from @AfterInserted.nodes('/root/row/@*') as T(N)

我也需要该字段的数据类型。像T.N.value('数据类型')?

由于

2 个答案:

答案 0 :(得分:1)

不确定这是否适用于您的目的,但是:

SELECT SQL_VARIANT_PROPERTY(your_column, 'BaseType')
FROM your_table

将列的字段类型返回为NVARCHAR

您还可以使用PrecisionScaleMaxLengthCollationTotalBytes作为SQL_VARIANT_PROPERTY的第二个参数。

答案 1 :(得分:0)

无需使用XML来获取与Trigger所在的表相关的元数据。您可以查询系统目录以直接获取信息。

触发器是一个带有object_id的对象,因此@@PROCID系统变量将在触发器的上下文中具有触发器本身的object_id

使用@@PROCID的值,您可以在该行的sys.objects查看该特定object_idparent_object_id字段将是object_id触发器所在的表。

使用parent_object_id的值,您可以查询sys.tables / sys.objects以获取表级信息,或查询sys.columns以获取列级信息。

以下示例说明了以上信息:

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET NOCOUNT ON
GO

-- DROP TABLE dbo.TriggerTest
IF (OBJECT_ID('dbo.TriggerTest') IS NULL)
BEGIN
    PRINT 'Creating TriggerTest...'
    CREATE TABLE dbo.TriggerTest (Col1 INT, Col2 VARCHAR(30), Col3 DATETIME)
END

-- 
IF (OBJECT_ID('dbo.TR_TriggerTest_IU') IS NOT NULL)
BEGIN
    PRINT 'Dropping TR_TriggerTest_IU...'
    DROP TRIGGER dbo.TR_TriggerTest_IU
END
GO

PRINT 'Creating TR_TriggerTest_IU...'
GO
CREATE TRIGGER dbo.TR_TriggerTest_IU
    ON dbo.TriggerTest
    AFTER INSERT, UPDATE
AS
BEGIN
    SET NOCOUNT ON

    -- get Table info
    SELECT  *
    FROM    sys.tables st
    WHERE   st.[object_id] = (  -- get parent_object_id of this Trigger
                                -- which will be the table that the
                                -- Trigger is on
                                SELECT  so.parent_object_id
                                FROM    sys.objects so
                                WHERE   so.[object_id] = @@PROCID
                            )

    -- get Column info
    SELECT  *
    FROM    sys.columns sc
    -- Custom types will repeat values of system_type_id and produce a
    -- cartesian product, so filter using "is_user_defined = 0"
    INNER JOIN  sys.types st
        ON  st.system_type_id = sc.system_type_id
        AND st.is_user_defined = 0
    WHERE   sc.[object_id] = (  -- get parent_object_id of this Trigger
                                -- which will be the table that the
                                -- Trigger is on
                                SELECT  so.parent_object_id
                                FROM    sys.objects so
                                WHERE   so.[object_id] = @@PROCID
                            )
END
GO

INSERT INTO dbo.TriggerTest (Col1, Col2, Col3) VALUES (1, 'a', GETDATE())