none
批量入主数据表插入数据量生成流水号 RRS feed

  • 问题

  • --触发器可以实现流水号,但不能传参数
    /*
    select * from tb1 --tb1为临时表
    name
    ----------
    aa
    bb
    cc
    aa
    bb
    cc
    
    (6 行受影响)
    */
    /*流水号生成规则OP(是传入的数据类型)+年+月+日+5位流水号(流水号原则,是每天的日期,从00001开始生成,当天数据导入两,就从第一次的基础增加流水号)*/
    --得出下面的结果,触发器不可以,不能传参数,
    /*
    select * from tb2 --tb2为主数据表
    id                 name
    ------------------ ----------
    OP1204290001       aa
    OP1204290002       bb
    OP1204290003       cc
    OP1204280001       aa
    OP1204280002       bb
    OP1204280003       cc
    
    (6 行受影响)
    
    */
    先谢过,第一在这里问题!

    2012年4月28日 9:29

答案

  • 只考虑楼主目前列出的规则, 不考虑参数传递, 可以参考下面的示例

    USE tempdb;
    GO
    
    CREATE TABLE tb2(
    	id char(13),
    	name varchar(10)
    );
    GO
    
    CREATE TRIGGER tr_insert_tb2
       ON  dbo.tb2
       INSTEAD OF INSERT-- 前置触发器
    AS 
    BEGIN;
    	SET NOCOUNT ON;
    
    	DECLARE
    		@id_str varchar(15),
    		@id int
    	;
    	-- 当前日期
    	SELECT
    		@id_str = 'OP' + CONVERT(char(6), GETDATE(), 12)
    	;
    	
    	-- 当前日期最大 ID
    	SELECT
    		@id = 1000000 + ISNULL(RIGHT(MAX(id), 5), 0)
    	FROM tb2
    	WHERE id LIKE @id_str + '%'
    	;
    	
    	-- 为新增的每条记录生成流水号
    	SELECT *
    		INTO #t
    	FROM inserted
    	;
    	
    	UPDATE #t SET
    		@id = @id + 1,
    		id = @id_str + RIGHT(@id, 5)
    	;
    	
    	-- 将数据插入正式表
    	INSERT tb2
    	SELECT * FROM #t
    	;
    END
    GO
    
    INSERT tb2(
    	name
    )
    SELECT 'aa' UNION ALL
    SELECT 'bb'
    ;
    
    INSERT tb2(
    	name
    )
    SELECT 'cc' UNION ALL
    SELECT 'dd' UNION ALL
    SELECT 'ee' UNION ALL
    SELECT 'ff' UNION ALL
    SELECT 'ff'
    ;
    
    SELECT * FROM tb2
    ;
    GO
    
    DROP TABLE tb2

    2012年5月2日 5:15

全部回复

  • 或许你可以试试看下列的方式。

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER TRIGGER tr_insert_tb1 
       ON  dbo.tb1
       AFTER INSERT
    AS 
    BEGIN
    	SET NOCOUNT ON;
    
    	INSERT INTO tb2 
    	SELECT 'OP' 
    					+ convert(varchar(8),GETDATE(),12) 
    					+ RIGHT('0000' + convert(varchar,(select count(name) from tb1)),5)
    				,name
    	FROM inserted
    
    END
    GO
    


    以上說明若有錯誤請指教,謝謝。
    http://www.dotblogs.com.tw/terrychuang/

    2012年4月28日 14:50
  • 触发器可以实现流水号,但不能传参数

    你可以利用表中字段来作为触发器中计算序号的参数。


    family as water

    2012年4月29日 7:10
  • 触发器的处理, 要注意一下, SQL Server 不支持行级触发, 所以要考虑如果一次性插入多条记录时, 是只触发一次的, 这种情况下生成的流水号要考虑避免重复

    2012年5月2日 4:39
  • 楼主提到的这个问题, 关键是在于楼主想怎么操作(楼主的问题只提到了想要什么样的渡口号, 没有提具体的操作是什么, 所以无法提供具体的实现)

    如果是想自动生成, 不涉及任何数据操作语句的调整, 那么考虑用触发器或者用户定义函数(做为字段的默认值), 这两种方式, 都不涉及参数传递, 如果需要其他数据, 这些数据可以考虑用表中的其他列来提供

    如果是在插入的语句中去嵌入生成流水号, 那么你可以写成用户定义函数, 想怎么传递参数都行

    2012年5月2日 4:43
  • 只考虑楼主目前列出的规则, 不考虑参数传递, 可以参考下面的示例

    USE tempdb;
    GO
    
    CREATE TABLE tb2(
    	id char(13),
    	name varchar(10)
    );
    GO
    
    CREATE TRIGGER tr_insert_tb2
       ON  dbo.tb2
       INSTEAD OF INSERT-- 前置触发器
    AS 
    BEGIN;
    	SET NOCOUNT ON;
    
    	DECLARE
    		@id_str varchar(15),
    		@id int
    	;
    	-- 当前日期
    	SELECT
    		@id_str = 'OP' + CONVERT(char(6), GETDATE(), 12)
    	;
    	
    	-- 当前日期最大 ID
    	SELECT
    		@id = 1000000 + ISNULL(RIGHT(MAX(id), 5), 0)
    	FROM tb2
    	WHERE id LIKE @id_str + '%'
    	;
    	
    	-- 为新增的每条记录生成流水号
    	SELECT *
    		INTO #t
    	FROM inserted
    	;
    	
    	UPDATE #t SET
    		@id = @id + 1,
    		id = @id_str + RIGHT(@id, 5)
    	;
    	
    	-- 将数据插入正式表
    	INSERT tb2
    	SELECT * FROM #t
    	;
    END
    GO
    
    INSERT tb2(
    	name
    )
    SELECT 'aa' UNION ALL
    SELECT 'bb'
    ;
    
    INSERT tb2(
    	name
    )
    SELECT 'cc' UNION ALL
    SELECT 'dd' UNION ALL
    SELECT 'ee' UNION ALL
    SELECT 'ff' UNION ALL
    SELECT 'ff'
    ;
    
    SELECT * FROM tb2
    ;
    GO
    
    DROP TABLE tb2

    2012年5月2日 5:15