sql2008触发器的问题,在线等,谢谢!

joesangui 2010-07-11 11:49:31
我在sql2008的一个表里建立了一个触发器,当有数据插入更新另一个表中的数据,当这个更新表在同一个数据库中是没有问题的,当这个表在本地的其他数据库就不行,也就是改了表名,变成 数据库.dbo.表名,而且插入的脚本在查询分析器里执行正常,怎么在触发器里就是不行?!请高人指点一下啊!
...全文
574 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
qjx_20 2010-09-01
  • 打赏
  • 举报
回复
joesangui 2010-07-14
  • 打赏
  • 举报
回复
多谢各位,由于是在别的系统中做集成,所以忽略了其系统中的数据连接用户,所以老是操作不成功,把连接用户的权限扩展到两个数据库就好了。
总结:触发器的执行权限不是所有者的执行权限,而是触发者的执行权限,我一直纠缠在所有者上,走了弯路!
xman_78tom 2010-07-13
  • 打赏
  • 举报
回复
当然,在将数据库的 dbo 作为身份验证情况下扩展模拟作用域会让该数据库下所有的模拟账户都具有访问目标数据库或实例的权利。为了只让特定的帐户具有访问目标数据库或实例的权利,可以使用模块签名的方法。
xman_78tom 2010-07-13
  • 打赏
  • 举报
回复

-- 修改一下测试内容,使其更具一般性
use db1
go
-- 在 db1 中创建用户帐户 test
create user test without login;
go
grant select,delete on dbo.tab to test;
go

-- 由 test 删除 db1.dbo.tab 表中的行
execute as user='test';
delete from dbo.tab where id=1;
select user_name() username;
revert;
go

select * from db1.dbo.tab;
select * from db2.dbo.tab;
xman_78tom 2010-07-13
  • 打赏
  • 举报
回复
举个例子说明一下

-- 创建测试数据库
use master
go
create database db1;
go
create database db2;
go

use db1
go
create table dbo.tab (id int);
go
insert into dbo.tab values(1);
go
-- 触发器确保删除 db1.dbo.tab 表行时,db2.dbo.tab 表上对应的 fid 列的值都设置 null
create trigger dbo.trg_tab_delete on dbo.tab
with execute as owner -- 让触发器以 dbo 的身份运行
for delete
as
update t set fid=null from db2.dbo.tab t, deleted i where t.fid=i.id;
go

use db2
go
create table dbo.tab (id int, fid int);
go
insert into dbo.tab values(1,1);
insert into dbo.tab values(2,1);
go

-- 关键:扩展模拟作用域
-- 有以下两个条件:
-- 其一,模拟账户的身份验证者(即账户所在数据库的 dbo)必须在目标数据库或实例内是可信的。
-- 即 dbo 在目标数据库所对应的用户帐户必须拥有目标数据库的 AUTHENTICATE 权限。
-- 由于 db1 和 db2 数据库的所有者为同一个登陆帐户,因此这里不必配置权限。
-- 其二,模拟账户所在的数据库必须被标记为可信的。
alter database db1 set trustworthy on;
go

-- 测试
delete from db1.dbo.tab where id=1;
go
select * from db1.dbo.tab;
select * from db2.dbo.tab;
/*
1 NULL
2 NULL
*/

use master
go
drop database db1;
go
drop database db2;
go
joesangui 2010-07-13
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 xman_78tom 的回复:]

SQL Server 的触发器默认是以调用者的身份运行的,也就是说是以激发触发器的语句的执行者身份运行。因此,问题在于是否每一个激发触发器的语句的执行者是否都具有访问其他数据库上对象的权限。

针对 lz 的问题,有两种解决方法:
其一,如果触发器的所有者与引用对象的所有者一致(如,都是 dbo),启用“跨数据库所有权链”(sp_configure 'cross db ownership ……
[/Quote]

你好,两种方法我都试了,还是不行,就连简单的插入都不行,但是本地表插入就可以,不知道sql2008怎么这么麻烦!!!
另外,有没有触发器运行不正常不影响原数据表的操作,我现在触发器有问题,原数据表也不能插入数据!!!
htl258_Tony 2010-07-11
  • 打赏
  • 举报
回复

USE 正确的库名
GO
ALTER TRIGGER [accessevent_trigger] ON [dbo].[AccessEvent]
AFTER INSERT
AS
BEGIN
DECLARE @AccessTime DATETIME, @DoorName VARCHAR(128), @SiteCode SMALLINT, @CardNum INT
SET @AccessTime = GETDATE()
SET @DoorName = 'myroom'
SET @SiteCode = 1
SET @CardNum = 11111
INSERT INTO mytmpdb.dbo.accessevent( TIMESTAMP, PointDoor, CardSite, CardNumber )
VALUES( @AccessTime, @DoorName, @SiteCode, @CardNum )

DECLARE cur_insert CURSOR FOR
SELECT i.TimeStamp, d.uiname, ISNULL(i.SiteCode, 0), ISNULL(i.NonABACardNumber, 0)
FROM inserted i, [dbo].[door] d
WHERE i.EventClass = 4
AND i.DoorIdHi = d.ObjectIdHi
AND i.DoorIdLo = d.ObjectIdLo
AND ISNULL(i.SiteCode, 0)<>0
AND ISNULL(i.NonABACardNumber, 0)<>0
AND d.uiname<>''

OPEN cur_insert

FETCH NEXT FROM cur_insert INTO @AccessTime,@DoorName,@SiteCode,@CardNum

WHILE @@FETCH_STATUS=0
BEGIN
INSERT INTO mytmpdb.dbo.accessevent( TIMESTAMP, PointDoor, CardSite, CardNumber )
VALUES(@AccessTime, @DoorName, @SiteCode, @CardNum )
FETCH NEXT FROM cur_insert INTO @AccessTime,@DoorName,@SiteCode,@CardNum
END
CLOSE cur_insert
DEALLOCATE cur_insert
END
GO
没发现什么大问题。你确定在查询分析器执行正常,确认触发器创建正确的数据库上吗?
以上代码做一点小改动,再试一下。
joesangui 2010-07-11
  • 打赏
  • 举报
回复
下面是我触发器的脚本,中间有条直接插入数据的测试语句,在sql2000下,直接插入数据的测试语句和游标都可以实现,执行正常,在sql2005下,直接插入数据的测试语句正常,游标不正常执行,在sql2008下,两种方式都不正常!真的很郁闷!

ALTER Trigger [accessevent_trigger] On [dbo].[AccessEvent]
after INSERT
AS
begin
Declare @AccessTime datetime, @DoorName varchar(128),@SiteCode smallint,@CardNum int
set @AccessTime = getdate()
set @DoorName = 'myroom'
set @SiteCode = 1
set @CardNum = 11111
insert into mytmpdb.dbo.accessevent(TimeStamp,PointDoor,CardSite,CardNumber)
values(@AccessTime,@DoorName,@SiteCode,@CardNum )

DECLARE cur_insert CURSOR FOR
select i.TimeStamp,d.uiname,isnull(i.SiteCode,0),isnull(i.NonABACardNumber,0)
From inserted i,door d
where i.EventClass = 4 and i.DoorIdHi = d.ObjectIdHi and i.DoorIdLo = d.ObjectIdLo

OPEN cur_insert

FETCH NEXT FROM cur_insert
INTO @AccessTime,@DoorName,@SiteCode,@CardNum

WHILE @@FETCH_STATUS = 0
BEGIN
if @SiteCode<>0 and @CardNum<>0 and @DoorName <> ''
Begin
insert into mytmpdb.dbo.accessevent(TimeStamp,PointDoor,CardSite,CardNumber)
values(@AccessTime,@DoorName,@SiteCode,@CardNum )
end
FETCH NEXT FROM cur_insert
INTO @AccessTime,@DoorName,@SiteCode,@CardNum

END
CLOSE cur_insert
DEALLOCATE cur_insert

end
htl258_Tony 2010-07-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 joesangui 的回复:]
同一服务器,用sa登陆
[/Quote]
如果这样,有触发到应该没问题才对,贴出你触发器的脚本看下。
joesangui 2010-07-11
  • 打赏
  • 举报
回复
同一服务器,用sa登陆
htl258_Tony 2010-07-11
  • 打赏
  • 举报
回复
同一服务器吗,登录用户有没有另一数据库的相应操作权限?
joesangui 2010-07-11
  • 打赏
  • 举报
回复
我也认为加了限定名没问题,可是实际就是不行,我不知道触发器触发时用的什么用户,我把这两个数据库的所有者都设置成同一个人了,但是就是在触发器里执行不行,在查询分析器里没有问题!
永生天地 2010-07-11
  • 打赏
  • 举报
回复
帮顶。
SQL77 2010-07-11
  • 打赏
  • 举报
回复
[Quote=引用楼主 joesangui 的回复:]
我在sql2008的一个表里建立了一个触发器,当有数据插入更新另一个表中的数据,当这个更新表在同一个数据库中是没有问题的,当这个表在本地的其他数据库就不行,也就是改了表名,变成 数据库.dbo.表名,而且插入的脚本在查询分析器里执行正常,怎么在触发器里就是不行?!请高人指点一下啊!
[/Quote]
加了限定名没问题吧,除非你这个用户没权限操作些数据库
joesangui 2010-07-11
  • 打赏
  • 举报
回复
还有一个问题,就是我从sql2000导入的数据库在sql2008中全部存储过程都锁定不能修改了,我也增加了管理员的权限,依然不能访问?!
thinclient 2010-07-11
  • 打赏
  • 举报
回复
不知,顶
王向飞 2010-07-11
  • 打赏
  • 举报
回复
mark
chen_hh2 2010-07-11
  • 打赏
  • 举报
回复
帮顶,求解
xman_78tom 2010-07-11
  • 打赏
  • 举报
回复
SQL Server 的触发器默认是以调用者的身份运行的,也就是说是以激发触发器的语句的执行者身份运行。因此,问题在于是否每一个激发触发器的语句的执行者是否都具有访问其他数据库上对象的权限。

针对 lz 的问题,有两种解决方法:
其一,如果触发器的所有者与引用对象的所有者一致(如,都是 dbo),启用“跨数据库所有权链”(sp_configure 'cross db ownership chaining ', 1)。这种方法有安全隐患,不推荐使用。

其二,推荐使用 execute as 切换触发器或语句运行的安全上下文(适用于 SQL Server 2005)。例如,在触发器定义中添加 execute as owner 子句让触发器以所有者身份运行,要求该触发器的所有者对应的登陆帐户需要在目标数据库中有访问对象的权限。按 lz 定义触发器,像下面这样定义,应该就可以了
create trigger [dbo].[accessevent_trigger] On [dbo].[AccessEvent]
with execute as owner
for insert
as
...
go
joesangui 2010-07-11
  • 打赏
  • 举报
回复
谢谢,这些还要到上班才可以测试!
谢谢大家的支持,我会陆续上传相关电子书 由于体积较大,本书分两卷压缩,请都下载完再解压! Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(一) http://download.csdn.net/source/3268267 Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(二) http://download.csdn.net/source/3268312 内容简介   本书是专门为oracle应用开发人员提供的sql和pl/sql编程指南。通过学习本书,读者不仅可以掌握oracle常用工具oracle universal installer、net comfiguration assistant、sql developer、sql*plus的作用及使用方法,而且可以掌握sql语句和pl/sql的各种基础知识和高级特征(记录类型、集合类型、对象类型、大对象类型)。   除了为读者提供编写sql语句和开发pl/sql块的方法外,本书还为应用开发人员提供了一些常用的pl/sql系统包。通过使用这些pl/sql系统包,应用开发人员可以开发出功能更强大的数据库应用程序。本书不仅适合sql和pl/sql初学者,也适合于有经验的oracle应用开发人员。 前言 第一部分 sql和pl/sql相关工具  第1章 在windows 平台上安装oracle database 11g  第2章 配置网络服务名  第3章 使用sql database  第4章 使用sql*plus 第二部分 sql  第5章 sql和pl/sql综述  第6章 简单查询  第7章 sql单行函数  第8章 操纵数据  第9章 复杂查询  第10章 管理常用对象 第三部分 pl/sql  第11章 pl/sql基础  第12章 访问oracle  第13章 编写控制结构  第14章 使用复合数据类型  第15章 使用游标  第16章 异常处理 . 第17章 本地动态sql  第18章 pl/sql过程  第19章 pl/sql函数  第20章 pl/sql包  第21章 触发器  第22章 使用对象类型 第四部分 pl/sql系统包  第23章 使用大对象  第24章 读写os文件  第25章 开发多媒体应用  第26章 开发web应用  第27章 dbms_sq动态sql  第28章 管理统计  第29章 使用数据库资源管理器  第30章 数据加密和解密  第31章 使用调度程序  第32章 使用flashback  第33章 使用重定义联机表  第34章 修正损坏块  第35章 使用日里民挖掘  第36章 使用管道  第37章 使用精细访问控制  第38章 使用精细审计  第39章 使用预警事件  第40章 转换rowid  第41章 其他常用包 习题答案
谢谢大家的支持,我会陆续上传相关电子书 由于体积较大,本书分两卷压缩,请都下载完再解压! Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(一) http://download.csdn.net/source/3268267 Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(二) http://download.csdn.net/source/3268312 内容简介   本书是专门为oracle应用开发人员提供的sql和pl/sql编程指南。通过学习本书,读者不仅可以掌握oracle常用工具oracle universal installer、net comfiguration assistant、sql developer、sql*plus的作用及使用方法,而且可以掌握sql语句和pl/sql的各种基础知识和高级特征(记录类型、集合类型、对象类型、大对象类型)。   除了为读者提供编写sql语句和开发pl/sql块的方法外,本书还为应用开发人员提供了一些常用的pl/sql系统包。通过使用这些pl/sql系统包,应用开发人员可以开发出功能更强大的数据库应用程序。本书不仅适合sql和pl/sql初学者,也适合于有经验的oracle应用开发人员。 前言 第一部分 sql和pl/sql相关工具  第1章 在windows 平台上安装oracle database 11g  第2章 配置网络服务名  第3章 使用sql database  第4章 使用sql*plus 第二部分 sql  第5章 sql和pl/sql综述  第6章 简单查询  第7章 sql单行函数  第8章 操纵数据  第9章 复杂查询  第10章 管理常用对象 第三部分 pl/sql  第11章 pl/sql基础  第12章 访问oracle  第13章 编写控制结构  第14章 使用复合数据类型  第15章 使用游标  第16章 异常处理 . 第17章 本地动态sql  第18章 pl/sql过程  第19章 pl/sql函数  第20章 pl/sql包  第21章 触发器  第22章 使用对象类型 第四部分 pl/sql系统包  第23章 使用大对象  第24章 读写os文件  第25章 开发多媒体应用  第26章 开发web应用  第27章 dbms_sq动态sql  第28章 管理统计  第29章 使用数据库资源管理器  第30章 数据加密和解密  第31章 使用调度程序  第32章 使用flashback  第33章 使用重定义联机表  第34章 修正损坏块  第35章 使用日里民挖掘  第36章 使用管道  第37章 使用精细访问控制  第38章 使用精细审计  第39章 使用预警事件  第40章 转换rowid  第41章 其他常用包 习题答案

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧