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

Sql server 如何知道触发器中字段的数据类型?,sql-server,triggers,Sql Server,Triggers,如何知道触发器中字段的数据类型。插入后,我能够在触发器中获取字段名及其值,如下所示: DECLARE @AfterInserted XML SELECT @AfterInserted = ( SELECT * FROM INSERTED WHERE User_Key = User_Key FOR XML RAW, ROOT ); CREATE TABLE #XML( FieldName n

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

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(“数据类型”)的东西


谢谢

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

SELECT SQL_VARIANT_PROPERTY(your_column, 'BaseType')
FROM your_table
将返回列的字段类型为
NVARCHAR


您还可以使用
精度
比例
最大长度
排序规则
总字节数
作为的第二个参数。

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

SELECT SQL_VARIANT_PROPERTY(your_column, 'BaseType')
FROM your_table
将返回列的字段类型为
NVARCHAR


您还可以使用
精度
比例
最大长度
排序规则
总字节数
作为的第二个参数。

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

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

使用
@@PROCID
的值,您可以在行的
sys.objects
中查找特定的
对象id
父对象id
字段将是触发器所在表的
对象id

使用
parent\u object\u 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())

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

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

使用
@@PROCID
的值,您可以在行的
sys.objects
中查找特定的
对象id
父对象id
字段将是触发器所在表的
对象id

使用
parent\u object\u 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())

为什么首先要将整个结构转换为XML?您的代码能够处理触发器处理多行而不是一行的情况吗?在我的例子中,一次只处理一行。为什么要首先将整个结构转换为XML?您的代码能够处理触发器处理多行而不是一行的情况吗?在我的例子中,一次只处理一行。这就是始终将nvarchar作为数据类型返回。甚至我的字段的数据类型也不确定为什么:
SELECT SQL\u VARIANT\u PROPERTY(100,'BaseType')
返回
int
(我在发布前对一个表进行了尝试)我的意思是你应该在
INSERTED
中的值上使用这些值,这些值将是实际的数据类型。这是一直以数据类型返回nvarchar。甚至我的字段的数据类型也不确定为什么:
SELECT SQL\u VARIANT\u PROPERTY(100,'BaseType')
返回
int
(我在发布前对一个表进行了尝试)我的意思是您应该在
INSERTED
中的值上使用这些值,这些值将是实际的数据类型。