sql-server - 循环触发器内的所有列

标签 sql-server triggers

我的表中有大约 51 列,我需要在插入触发器中的 45 列上应用一个数学公式。我在 SQL 用户定义函数中有我的公式,现在我想循环插入的所有列并将它们传递给条件 [所以我只选择 45 列],然后应用函数来获取我的值。有什么好的办法吗?

哦,这是我的第一个触发器,我真的不知道该怎么做,我正在 MSDN 上搜索它,但还没有找到任何东西。

Create TABLE Project_5_Data (
DataID BIGINT IDENTITY(1,1) NOT NULL,
FileID BIGINT,
LogTime DATETIME,
F0_8 DECIMAL(18,2),
F1 DECIMAL(18,2),
F1_25 DECIMAL(18,2),
F1_60 DECIMAL(18,2),
F2 DECIMAL(18,2),
F2_5 DECIMAL(18,2),
F3_15 DECIMAL(18,2),
F4 DECIMAL(18,2),
F5 DECIMAL(18,2),
F6_3 DECIMAL(18,2),
F8 DECIMAL(18,2),
F10 DECIMAL(18,2),
F12_5 DECIMAL(18,2),
F16 DECIMAL(18,2),
F20 DECIMAL(18,2),
F25 DECIMAL(18,2),
F31_5 DECIMAL(18,2),
F40 DECIMAL(18,2),
F50 DECIMAL(18,2),
F63 DECIMAL(18,2),
F80 DECIMAL(18,2),
F100 DECIMAL(18,2),
F125 DECIMAL(18,2),
F160 DECIMAL(18,2),
F200 DECIMAL(18,2),
F250 DECIMAL(18,2),
F315 DECIMAL(18,2),
F400 DECIMAL(18,2),
F500 DECIMAL(18,2),
F630 DECIMAL(18,2),
F800 DECIMAL(18,2),
F1000 DECIMAL(18,2),
F1250 DECIMAL(18,2),
F1600 DECIMAL(18,2),
F2000 DECIMAL(18,2),
F2500 DECIMAL(18,2),
F3150 DECIMAL(18,2),
F4000 DECIMAL(18,2),
F5000 DECIMAL(18,2),
F6300 DECIMAL(18,2),
F8000 DECIMAL(18,2),
F10000 DECIMAL(18,2),
F12500 DECIMAL(18,2),
F16000 DECIMAL(18,2),
F20000 DECIMAL(18,2),
    TotA DECIMAL(18,2),
TotC DECIMAL(18,2),
TotZ DECIMAL(18,2),
Primary Key ( DataID)
)

我想迭代所有以 F 开头的列(FileID 命名列除外),然后应用我的函数 [dbo].[FindLAValue],该函数将 DEcimal 输入作为参数。

我只需要知道如何在触发器内的“插入”列或该表中的所有列上循环。谢谢。

最佳答案

不是答案,但我希望这可以节省您的时间 -

DECLARE
      @LogTime DATETIME
    , @F0_8 DECIMAL(18,2)
    , @F1 DECIMAL(18,2)
    , @F1_25 DECIMAL(18,2)
    , @F1_60 DECIMAL(18,2)
    , @F2 DECIMAL(18,2)
    , @F2_5 DECIMAL(18,2)
    , @F3_15 DECIMAL(18,2)
    , @F4 DECIMAL(18,2)
    , @F5 DECIMAL(18,2)
    , @F6_3 DECIMAL(18,2)
    , @F8 DECIMAL(18,2)
    , @F10 DECIMAL(18,2)
    , @F12_5 DECIMAL(18,2)
    , @F16 DECIMAL(18,2)
    , @F20 DECIMAL(18,2)
    , @F25 DECIMAL(18,2)
    , @F31_5 DECIMAL(18,2)
    , @F40 DECIMAL(18,2)
    , @F50 DECIMAL(18,2)
    , @F63 DECIMAL(18,2)
    , @F80 DECIMAL(18,2)
    , @F100 DECIMAL(18,2)
    , @F125 DECIMAL(18,2)
    , @F160 DECIMAL(18,2)
    , @F200 DECIMAL(18,2)
    , @F250 DECIMAL(18,2)
    , @F315 DECIMAL(18,2)
    , @F400 DECIMAL(18,2)
    , @F500 DECIMAL(18,2)
    , @F630 DECIMAL(18,2)
    , @F800 DECIMAL(18,2)
    , @F1000 DECIMAL(18,2)
    , @F1250 DECIMAL(18,2)
    , @F1600 DECIMAL(18,2)
    , @F2000 DECIMAL(18,2)
    , @F2500 DECIMAL(18,2)
    , @F3150 DECIMAL(18,2)
    , @F4000 DECIMAL(18,2)
    , @F5000 DECIMAL(18,2)
    , @F6300 DECIMAL(18,2)
    , @F8000 DECIMAL(18,2)
    , @F10000 DECIMAL(18,2)
    , @F12500 DECIMAL(18,2)
    , @F16000 DECIMAL(18,2)
    , @F20000 DECIMAL(18,2)
    , @TotA DECIMAL(18,2)
    , @TotC DECIMAL(18,2)
    , @TotZ DECIMAL(18,2)
    , @DataID BIGINT
    , @FileID BIGINT

DECLARE project_5_data CURSOR LOCAL READ_ONLY FAST_FORWARD FOR
SELECT
      DataID
    , FileID
    , LogTime
    , F0_8
    , F1
    , F1_25
    , F1_60
    , F2
    , F2_5
    , F3_15
    , F4
    , F5
    , F6_3
    , F8
    , F10
    , F12_5
    , F16
    , F20
    , F25
    , F31_5
    , F40
    , F50
    , F63
    , F80
    , F100
    , F125
    , F160
    , F200
    , F250
    , F315
    , F400
    , F500
    , F630
    , F800
    , F1000
    , F1250
    , F1600
    , F2000
    , F2500
    , F3150
    , F4000
    , F5000
    , F6300
    , F8000
    , F10000
    , F12500
    , F16000
    , F20000
    , TotA
    , TotC
    , TotZ
FROM dbo.project_5_data

OPEN project_5_data
FETCH NEXT FROM project_5_data INTO
      @DataID
    , @FileID
    , @LogTime
    , @F0_8
    , @F1
    , @F1_25
    , @F1_60
    , @F2
    , @F2_5
    , @F3_15
    , @F4
    , @F5
    , @F6_3
    , @F8
    , @F10
    , @F12_5
    , @F16
    , @F20
    , @F25
    , @F31_5
    , @F40
    , @F50
    , @F63
    , @F80
    , @F100
    , @F125
    , @F160
    , @F200
    , @F250
    , @F315
    , @F400
    , @F500
    , @F630
    , @F800
    , @F1000
    , @F1250
    , @F1600
    , @F2000
    , @F2500
    , @F3150
    , @F4000
    , @F5000
    , @F6300
    , @F8000
    , @F10000
    , @F12500
    , @F16000
    , @F20000
    , @TotA
    , @TotC
    , @TotZ

WHILE @@FETCH_STATUS = 0 BEGIN

    -- INSERT STATEMENT HERE

    FETCH NEXT FROM project_5_data INTO
      @DataID
    , @FileID
    , @LogTime
    , @F0_8
    , @F1
    , @F1_25
    , @F1_60
    , @F2
    , @F2_5
    , @F3_15
    , @F4
    , @F5
    , @F6_3
    , @F8
    , @F10
    , @F12_5
    , @F16
    , @F20
    , @F25
    , @F31_5
    , @F40
    , @F50
    , @F63
    , @F80
    , @F100
    , @F125
    , @F160
    , @F200
    , @F250
    , @F315
    , @F400
    , @F500
    , @F630
    , @F800
    , @F1000
    , @F1250
    , @F1600
    , @F2000
    , @F2500
    , @F3150
    , @F4000
    , @F5000
    , @F6300
    , @F8000
    , @F10000
    , @F12500
    , @F16000
    , @F20000
    , @TotA
    , @TotC
    , @TotZ

END

CLOSE project_5_data
DEALLOCATE project_5_data

脚本生成器 -

DECLARE 
      @Name SYSNAME = 'schema_name.table_name' -- dbo.test_table
    , @SQL NVARCHAR(MAX)

SELECT @SQL = 'DECLARE' 
    + CHAR(13) + STUFF((
        SELECT CHAR(9) + ', @' + c.name + ' ' + UPPER(t.name) + 
            CASE WHEN t.name IN ('nvarchar', 'varchar', 'nchar', 'char', 'varbinary', 'binary')
                   THEN '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length AS VARCHAR(5)) END + ')'
                 WHEN t.name IN ('datetime2', 'time2', 'datetimeoffset') 
                   THEN '(' + CAST(c.scale AS NVARCHAR(5)) + ')'
                 WHEN t.name = 'decimal' 
                   THEN '(' + CAST(c.[precision] AS NVARCHAR(5)) + ',' + CAST(c.scale AS VARCHAR(5)) + ')'
                ELSE ''
            END + CHAR(13)
        FROM sys.columns c
        JOIN sys.types t ON c.system_type_id = t.system_type_id  AND c.system_type_id = t.user_type_id
        WHERE c.[object_id] = ob.[object_id]
        ORDER BY c.column_id
        FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, CHAR(9) + ' ')
    + CHAR(13) + 'DECLARE ' + ob.name + ' CURSOR LOCAL READ_ONLY FAST_FORWARD FOR' 
    + CHAR(13) + 'SELECT' + CHAR(13) + STUFF((
        SELECT CHAR(9) + ', ' + c.name + CHAR(13)
        FROM sys.columns c
        WHERE c.[object_id] = ob.[object_id]
        FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, CHAR(9) + ' ')
    + 'FROM ' + ob.sname + '.' + ob.oname
    + CHAR(13) + CHAR(13) + 'OPEN ' + ob.name
    + CHAR(13) + b.FetchBlock
    + CHAR(13) + 'WHILE @@FETCH_STATUS = 0 BEGIN'
    + CHAR(13) + CHAR(13) + CHAR(9) + '-- INSERT STATEMENT HERE'
    + CHAR(13) + CHAR(13) + CHAR(9) + b.FetchBlock
    + CHAR(13) + 'END'
    + CHAR(13) + CHAR(13) + 'CLOSE ' + ob.name
    + CHAR(13) + 'DEALLOCATE ' + ob.name
FROM (
    SELECT 
          o.[object_id]
        , oname = o.name
        , sname = SCHEMA_NAME(o.[schema_id])
        , name = LOWER(o.name) 
    FROM sys.objects o 
    WHERE o.[type] IN ('V', 'U')
        AND SCHEMA_NAME(o.[schema_id]) + '.' + o.name = @Name
) ob
OUTER APPLY (
    SELECT FetchBlock = 'FETCH NEXT FROM ' + ob.name + ' INTO' + CHAR(13) + 
    STUFF((
        SELECT CHAR(9) + ', @' + c.name + CHAR(13)
        FROM sys.columns c
        WHERE c.[object_id] = ob.[object_id]
        FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, CHAR(9) + ' ')
) b

PRINT @SQL

关于sql-server - 循环触发器内的所有列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18512309/

相关文章:

mysql - 高度事务性系统中的触发器

sql-server - SQL Server调整顾问报告

sql-server - SQL Server 枢轴 : Displaying row values to column headers

sql - SQL Server NOLOCK 提示会返回部分写入的行吗?

sql - 表正在发生变化,触发器/函数可能看不到它(阻止平均成绩低于 2.5)

multithreading - Google Apps 脚本和表格 : appendRow() regularly overwrites the last row instead of appending a new row below

c# - 在查询中参数化 WHERE 子句

php - 使用 MacBook 作为 Mysql 本地服务器

wpf - XAML 触发器模板基于另一个元素设置可见性

wpf - 切换 ToggleButton 的 IsChecked 列表框选择