Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 从触发器执行时SQL语句未终止_Sql Server_Tsql - Fatal编程技术网

Sql server 从触发器执行时SQL语句未终止

Sql server 从触发器执行时SQL语句未终止,sql-server,tsql,Sql Server,Tsql,我提出了一个小的解决方案,当某个特定列被更新时,将客户数据行导出到csv文件 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER TRIGGER dbo.EXPORT_CUSTOMER_TYPE ON dbo.ADDRESSES AFTER UPDATE AS BEGIN SET NOCOUNT ON; IF (UPDATE(SYMBOL0)) BEGIN DECLARE @

我提出了一个小的解决方案,当某个特定列被更新时,将客户数据行导出到csv文件

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER dbo.EXPORT_CUSTOMER_TYPE 
   ON  dbo.ADDRESSES 
   AFTER UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    IF (UPDATE(SYMBOL0))
    BEGIN
        DECLARE @ADR_ID INT = (SELECT TOP 1 ID FROM inserted)
        
        -- TEMPORARY TABLE TO STORE THE COLUMNS WHICH SHOULD BE EXPORTED
        declare @ExportCols TABLE (
            idx int identity(1, 1),
            colName nvarchar(255)
        )

        -- READ INI FILE TO GET THE COMMA SEPARATED COLUMN NAMES
        declare @cols_dirtyString nvarchar(50);
        declare @outputfile nvarchar(255);
        exec dbo.lsp_ReadIniFile
            'C:\temp\SQL_READ_FILE_TEST\config.ini', 'ExportConfig', 'ExportColumns', @cols_dirtyString OUTPUT

        exec dbo.lsp_ReadIniFile
            'C:\temp\SQL_READ_FILE_TEST\config.ini', 'ExportConfig', 'OutputFile', @outputfile OUTPUT

        set @outputfile = REPLACE(REPLACE(@outputfile, '{date}', CONVERT(VARCHAR, GETDATE(), 23)), '{id}', CAST(@ADR_ID AS NVARCHAR))

        -- FILL THE TEMPORARY TABLE WITH COLUMN NAMES AND TEMPORARY IDS 
        INSERT INTO @ExportCols
        SELECT * FROM string_split(@cols_dirtyString, ',')

        -- LOOP THROUGH THE TEMP TABLE AND BUILD THE QUERY STRING
        declare @index int = 1;
        declare @rowcount int = (select count(*) from @ExportCols);
        declare @statement nvarchar(max) = 'SELECT '

        while (@index <= @rowcount)
        begin
            declare @colName nvarchar(255) = (select colName from @ExportCols where idx = @index)
            set @statement = @statement + @colName + ', '
            set @index = @index + 1;
        end

        set @statement = substring(@statement, 0, len(@statement))
        set @statement = @statement + ' FROM CobraDemoData.dbo.ADDRESSES WHERE ID = ' + CAST(@ADR_ID AS NVARCHAR)

        -- EXECUTE THE BUILT QUERY STRING
        DECLARE @ExportSQL nvarchar(max) = N'EXEC master.dbo.xp_cmdshell ''bcp "' + @statement + '" queryout "' + @outputfile + '" -T -c -t ";" -S T470p-DH\DEV'''
        EXEC(@ExportSQL)


    END
END
GO

有几件事需要注意。 我知道这不是解决这个需求的好方法。这是一个客户希望这样做。我别无选择。我还知道,当前脚本仅在插入的表只有一行时有效。这是一个早期状态,将得到解决

如果我在触发器内部对其本身执行逻辑,那么文件将被导出,并带有必要的数据,正如我所希望的那样。 但是,只要我将它放入触发器并更新一行,语句就永远不会结束。该文件已创建,但已永久使用。
我通常不使用tsql,因此任何帮助都将不胜感激

这看起来像一个巨大的。触发器对DML语句的影响应该最小。此触发器不仅有一段时间,而且还使用动态语句和xp\u cmdshell。如果DML语句中的行数超过1行,则该语句也有缺陷,因为它将处理插入表中的任意一行,仅此而已。在某些情况下,您也不会声明varchar的长度。所有这些逻辑都不应该在触发器中,触发器中的任何逻辑都应该解析插入的全部内容,而不是任意一行。@Larnu是的,我完全同意。但我别无选择。为了澄清这一点,我更新了帖子。你总是有选择的。触发器应该做的就是将相关数据插入池表中。然后,应该定期运行一个自动化流程来完成繁重的工作。您会发现,这里的任何人都不太可能帮助您创建一个固有缺陷的答案,因为该答案不会有帮助,并且很可能会吸引社区中有经验的成员的反对票;旁白:如果你知道触发器只能对一个更新的行正确工作,那么你应该检查并处理它,例如,如果选择Count*from Inserted>1抛出50000,“Foo\u Update\u trigger不能处理多个更新的行”,42;。