none
SQL SERVER 触发器问题,求教 RRS feed

  • 问题

  • 问题是这样的,我现在有两个数据库 Test 和Test1,其下个有一个ImEvent表,我想Test中ImEvent表里数据发生变化时用触发器插入到对应的Test1.ImEvent表中

    触发器如下,但出现一个问题,两种不同的写法,一个可以一个不可以

    use [Test]
    
    
    
    set ANSI_NULLS ON
    
    set QUOTED_IDENTIFIER ON
    
    go
    
    
    
    ALTER TRIGGER [ImEventTgigger]
    
    ON [dbo].[ImEvent]
    
    FOR INSERT
    
    AS
    
    Begin
    
    	declare @DeviceID numeric(18, 0)
    
    	declare @sql varchar(200)
    
    
    
    	select @DeviceID=DeviceID from INSERTED
    
    
    
    	insert into Test1.dbo.imevent(DeviceID) values (@DeviceID) 
    
    
    
    
    第二种写法
    
    
    use [Test]
    
    
    
    set ANSI_NULLS ON
    
    set QUOTED_IDENTIFIER ON
    
    go
    
    
    
    ALTER TRIGGER [ImEventTgigger]
    
    ON [dbo].[ImEvent]
    
    FOR INSERT
    
    AS
    
    Begin
    
    	declare @DeviceID numeric(18, 0)
    
    	declare @sql varchar(200)
    
    
    
    	select @DeviceID=DeviceID from INSERTED
    
    
    
    	set @sql = 'insert into Test1.dbo.ImEvent(DeviceID) values('+@DeviceID+')'
    
    	exec(@sql)
    
    End
    
    
    
    

    但是现在第二种写法语法没有问题,但是在TEST.IMevent表里添加数据的时候就添加不进去,第一种写法是可以的

    我用SQL跟踪器跟踪了下,发现第二种写法并没有对TEST1.IMevent表进行操作,反而是对TEST.IMevent表在做操作

     

    求教。

    因为我 我的数据库名称每年会变化,所以需要使用这种字符串连接形式(网友这么说的不知道是不是准确)

    我真实的插入数据名称是这样的

    	SELECT @NowYear= year(GETDATE())
    
    	select @DatabaseName='ImEvent'+ convert(varchar,@NowYear)
    
    
    
    insert into @DatabaseName.dbo.ImEvent(.....) values(.....)
    
    
    
    
    
    

    但是这样直接写不行,语法通不过,加上[]也不行
    网上查了说必须使用连接字符串,然后使用exec

    但是我试了就出现不能插入到指定数据库的情况了

     

    2010年7月12日 17:12

答案

  • set @sql = 'insert into Test1.dbo.ImEvent(DeviceID) values('+@DeviceID+')' 改为: set @sql = 'insert into Test1.dbo.ImEvent(DeviceID) values('+Cast(@DeviceID as Varchar(20))+')' 我测试过,没有问题 另: insert into @DatabaseName.dbo.ImEvent(.....) values(.....) 改为: Set @sql='insert into '+@DatabaseName+'.dbo.ImEvent(.....) values(.....)' Exec (@sql)
    Try SQL Server 2008 QQ:315054403 dgdba@hotmail.com
    2010年7月13日 1:26
  • 楼上回答正确,字符串拼接问题,你int类型需要转换为字符串才可以拼接到sql中。

    我补充一个问题:

    select @DeviceID=DeviceID from INSERTED

    这个写法是不正确的,INSERTED是一个集合,不一定是一条记录(批量插入的时候,你这个写法只能读取第一条记录)。

    你可以使用游标,或者连接表的方式来完成对INSERTED的监控。


    family as water
    2010年7月13日 1:56

全部回复

  • set @sql = 'insert into Test1.dbo.ImEvent(DeviceID) values('+@DeviceID+')' 改为: set @sql = 'insert into Test1.dbo.ImEvent(DeviceID) values('+Cast(@DeviceID as Varchar(20))+')' 我测试过,没有问题 另: insert into @DatabaseName.dbo.ImEvent(.....) values(.....) 改为: Set @sql='insert into '+@DatabaseName+'.dbo.ImEvent(.....) values(.....)' Exec (@sql)
    Try SQL Server 2008 QQ:315054403 dgdba@hotmail.com
    2010年7月13日 1:26
  • 楼上回答正确,字符串拼接问题,你int类型需要转换为字符串才可以拼接到sql中。

    我补充一个问题:

    select @DeviceID=DeviceID from INSERTED

    这个写法是不正确的,INSERTED是一个集合,不一定是一条记录(批量插入的时候,你这个写法只能读取第一条记录)。

    你可以使用游标,或者连接表的方式来完成对INSERTED的监控。


    family as water
    2010年7月13日 1:56
  • 直接 insert 就好了嘛, 没有必要用变量去转一次, 不然还得用游标去取每个值.

     insert into Test1.dbo.imevent(DeviceID) 
     select DeviceID from INSERTED

     

     

    2010年7月13日 4:37
  • 谢谢两位,确实是 类型的问题

    还是基础知识差了一点,概念理解不够

    再次谢谢大虾们指点迷津

    2010年7月13日 6:54
  • 是这样的,数据库每年会生成一个新的库

     

    所以这个地方需要用变量

    2010年7月13日 6:56
  • 现在又遇到一个问题

    Cast(@DeviceID as Varchar(20)) 

    如果@DeviceID 有值是可以的没有问题,也能插入

    但是@DeviceID 没有输入值为null 时,其他字段有值,这个时候触发器就不能够插入

     我发现如果有2个变量只要有一个是NULL就不执行

    不需要用Cast转换的字段也是这样,只要有null就不行

    请问如何解决,谢谢

    2010年7月13日 10:28