我在尝试分析一些数据库时偶然发现了这个触发器:
Create trigger [tbl_Details_Trigger] on [tbl_Details]
Instead of Insert
As
Insert into [tbl_Details]
Select * from inserted
Run Code Online (Sandbox Code Playgroud)
在我看来,这个触发器并没有做任何特别的事情,如果它被丢弃,结果将是一样的。我对吗?我错过了什么吗?
我已将一个简单的表添加到名为:aaa_log 的数据库中,其中包含列 :( id, name, op))
CREATE TABLE aaa_log (
[id] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[name] [varchar](50) NOT NULL,
[op] [varchar](50) NULL)
Run Code Online (Sandbox Code Playgroud)
id 列仅用于保持顺序的方式。
我for insert, update, delete使用以下脚本向数据库中的所有其他表添加了触发器 ( ):
declare @cmd varchar(max)
declare trigger_create cursor for
select 'Create trigger ['+TABLE_SCHEMA+'].[xxtr_'+TABLE_NAME+'_auto]
on ['+TABLE_SCHEMA+'].['+TABLE_NAME+'] fro insert,update,delete as
BEGIN
declare @op varchar(20)
if exists(SELECT * from inserted) and exists(SELECT * from deleted)
begin
set @op = ''update''
end
if exists(SELECT * from inserted) and not …Run Code Online (Sandbox Code Playgroud) 对于表,我可以实现“如果不存在”和“如果存在”如下:
--if table exists - drop
If OBJECT_ID('A','U') is not null
Drop Table [A]
--if table not exists - Create
If OBJECT_ID('A','U') is null
Create Table A([key] varchar(20), [value] varchar(max))
Run Code Online (Sandbox Code Playgroud)
但它在视图和触发器上的作用并不完全相同
我可以:
-- if exists - drop
If OBJECT_ID('VA','V') is not null
Drop view [VA]
Run Code Online (Sandbox Code Playgroud)
但是当我尝试相反的时候:
-- if not exists - create
If OBJECT_ID('VA','V') is null
Create view [VA] as Select * from [A]
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
关键字“view”附近的语法不正确
触发器也是如此。当我做:
-- if not exists - create
If OBJECT_ID('Trigger_A_ins','TR') is null
Create trigger [Trigger_A_ins] …Run Code Online (Sandbox Code Playgroud) 这似乎是一个奇怪的问题:
如果我有用户demo使用密码 Pass1234 呼叫
连接到 oracle 11g 时,我可以sqlplus在命令行中使用密码运行:在数据库主机上:
C:\> sqlplus demo/Pass1234
Run Code Online (Sandbox Code Playgroud)
或者远程机器
C:\> sqlplus demo/Pass1234@<ip>:1521/orcl
Run Code Online (Sandbox Code Playgroud)
我可以这样做而无需在命令行中提供密码并像这样公开它:
C:\> sqlplus demo
Run Code Online (Sandbox Code Playgroud)
然后我得到:
SQL*Plus: Release 11.1.0.7.0 bla bla bla
Copyright (c) bla bla bla
Enter password:
Run Code Online (Sandbox Code Playgroud)
然后我可以手动输入密码。
连接到 Oracle 12c 时,我可以从任何机器(使用密码)像这样连接:
C:\> sqlplus demo/Pass1234@<ip>:1521/pdborcl
Run Code Online (Sandbox Code Playgroud)
我的问题是:如何在不tnsnames.ora编辑和不在命令行中写入密码的情况下连接到 Oracle 12c ?
我还没有弄清楚是否可以从数据库主机上的 sqlplus 连接到 Oracle 12c,而无需提供 IP 或本地主机,并且无需编辑 tnsnames.ora,就像我在 Oracle 11g 中所做的那样?
更重要的是,我可以在不使用完全连接的情况下从远程机器(甚至到 Oracle 11g)执行此操作吗?
(装置手动给用户和在命令行分贝连接和密码,而不是像使用/NOLOG在命令,然后:SQL> connect demo/Pass1234@<ip>:1521/pdborcl)
谢谢!
我知道这可能看起来像一个奇怪的问题......
我有一个第三方数据库和服务,我想通过在DML触发器对其进行监视INSERT,UPDATE并且DELETE每个表的。
但是,唉,我在TRUNCATE TABLE被调用时遇到了问题,因为它没有激活DELETE触发器。
我正在寻找一种“重载”的方法TRUNCATE TABLE,例如:
DELETE FROM X; --remove all rows
TRUNCATE TABLE X; --truncate the empty table
Run Code Online (Sandbox Code Playgroud)
或者在截断之前激活一些 DDL 触发器,这样我就可以检查哪些行将被截断。
如果还有其他建议,我会很高兴。
这样的事情可能吗?
编辑
我不想禁用truncate我只想监视数据。
它是第 3 方数据库,并且被我无法控制的服务使用,因此我无法阻止truncate.
我只是想监视更改,目前无法跟踪由truncate命令引起的记录删除。
谢谢!
我问这个问题的方式是尝试了解我遇到的类似情况,并尝试了解插入视图是如何工作的。
我有这些表:
Create table A([id] int primary key not null, value nvarchar(50) NULL)
Create table B([id] int primary key not null, value nvarchar(50) NULL)
Run Code Online (Sandbox Code Playgroud)
我从两个表创建视图,如下所示:
create View V as (select * from A) UNION ALL (select * from B)
Run Code Online (Sandbox Code Playgroud)
我在 V 视图上有这个触发器:
Create trigger v_trig on V instead of insert AS
insert into v (id,value) select id,value from inserted
Run Code Online (Sandbox Code Playgroud)
当我尝试插入到我的视图中时,出现以下错误:
消息 4436,级别 16,状态 12,过程 v_trig,第 2 行
UNION ALL 视图“db.dbo.V”不可更新,因为未找到分区列
我有一个具有类似视图(带有union all)的数据库,出于某种原因,我可以毫无问题地插入它,我试图理解为什么。
我应该怎么做才能允许插入到诸如视图之类的视图中?有没有办法以插入的方式决定(不更改触发器)哪个是视图的默认表?
我有一个多会话数据库。很少有会话将多行插入到数据库中。并且一个会话从此表中选择。
有时我在 SELECT 查询上遇到死锁,我不明白为什么。
例如:假设这个表
Create Table t1([id] int identity(1,1), [column] varchar(max))
Run Code Online (Sandbox Code Playgroud)
插入是这样的:(我是从“之后”触发器中进行的)
Begin Transaction
Insert into t1 WITH (TABLOCKX) ([column]) values ('value 1'), ('value 2') ... ('value N')
Commit Transaction
Run Code Online (Sandbox Code Playgroud)
选择是这样的:
Select TOP 10 [id],[column] from t1 order by id
Run Code Online (Sandbox Code Playgroud)
对插入的锁定意味着在 DB 中保持会话插入的顺序。
每次我在一个事务中只锁定一张表。我试图通过一个会话插入和第二个会话来恢复僵局,但我失败了。在我添加 TABLOCKX 之前,我从未遇到过僵局。
所以我的问题是:
假设我有下表:
Create Table [dbo].[Test_IP]
(
[IP] varchar(40),
[IPType] varchar(6)
)
Run Code Online (Sandbox Code Playgroud)
这个表上有更多的触发器,但它们都是 AFTER 触发器,它是一个大数据库,有很多表、视图和存储过程,并且它被多个进程使用。
我添加了一个日志表和这样的触发器
Create Table [dbo].[Log_Test_IP]
(
[Action] varchar(10),
[IP] varchar(40),
[IPType] varchar(6)
)
GO
Create Trigger MYTR_Log_Test_IP_INS On [dbo].[Test_IP] After insert AS
BEGIN
insert into [dbo].[Log_Test_IP]([Action],[IP],[IPType])
select 'Insert', [IP], [IPType] from inserted
END
GO
Create Trigger MYTR_Log_Test_IP_DEL On [dbo].[Test_IP] After delete AS
BEGIN
insert into [dbo].[Log_Test_IP]([Action],[IP],[IPType])
select 'Delete', [IP], [IPType] from deleted
END
GO
Run Code Online (Sandbox Code Playgroud)
现在我进入了有趣的部分:当我直接插入到Test_IP表中时,我可以看到 Insert 触发器正在工作,但是当它从应用程序或服务(我不知道它是做什么的)定期工作时,我不知道看到日志表中的任何插入记录,我只能看到“删除”记录,即使它在开始时是空的。
我的结论是有一些方法可以绕过触发器,数据库中有很多触发器和存储过程,我不知道去哪里找。
所以,我的问题是如何绕过触发器?
我只有一张桌子Insert,Delete而且Select(没有Update)
在插入时,有时使用会话锁 ( WITH (TABLOCKX))
我有一个使用 ADO 的程序,它Select从表中使用RecordSet::Open命令打开一个简单的顺序查询。
喜欢:
Select * from t1 where id >= @from_id And >= @to_id`
Run Code Online (Sandbox Code Playgroud)
或者:
Select top(10) * from t1 where id >= @id Order by id
Run Code Online (Sandbox Code Playgroud)
id 列是一Identity列。
当我打开查询时,有时会陷入僵局。(表被Insert查询锁定,id 列的索引被 锁定Select)
我正在努力防止僵局。
我应该打开选择查询WITH(NOLOCK)吗?它可以防止死锁吗?
sql-server ×8
trigger ×4
deadlock ×2
view ×2
nolock ×1
oracle ×1
oracle-12c ×1
sqlplus ×1
truncate ×1