oracle触发器关系表达式,INSTEAD OF触发器的表达式和计算列-入门基础-Oracle频道-中国IT实验室...

本文探讨了视图选择列表中包含复杂表达式的情况,如常数、函数或多列组合表达式。当在这些视图上定义INSTEADOF触发器时,触发器需要具备相应逻辑来处理INSERT和UPDATE操作。举例说明了如何处理不映射到任何基表列的表达式,以及如何处理引用计算列或转换基表列值的视图表达式。触发器逻辑可能需要解析插入值或执行逆运算来确定基表中正确的列值。
摘要由CSDN通过智能技术生成

视图的选择列表可以包含除简单表达式(仅由一个列名构成)以外的其它表达式。这些视图上的 INSTEAD OF 触发器必须具有相应的逻辑,能够正确地确定 INSERT 和 UPDATE 触发器上指定的值中哪些值必须设置到基表中的列。此类表达式的示例包括:

◆不映射到任何表中任何列的视图表达式,如常数或某些类型的函数。

◆映射到多列的视图表达式,如由两个或更多列的串联字符串组成的复杂表达式。

◆转换单个基表列的值的视图表达式,如引用函数中的列。

这些情况还适合作为简单表达式的视图列,这些视图列引用基表中的计算列。定义计算列的表达式可与视图选择列表中的更复杂表达式具有相同的形式。

视图可在其不映射到任何基表列的选择列表中包含表达式,例如:

CREATE VIEW ExpressionView

AS

SELECT *, GETDATE() AS TodaysDate

FROM Northwind.dbo.Employees

虽然 TodaysDate 列并不映射到任何表列,但是 Microsoft? SQL Server? 2000 必须在将其传递到在 ExpressionView 上定义的 INSTEAD OF 触发器的 inserted 表中生成 TodaysDate 列。然而 inserted.TodaysDate 列可为空,所以引用 ExpressionView 的 INSERT 不必为该列提供值。因为表达式不映射到表中的列,所以触发器会忽略 INSERT 在该列中提供的任何值。

相同的方法应该应用于简单视图表达式,这些表达式引用基表中的计算列,而基表也生成不依赖于其它列的结果,例如:

CREATE TABLE ComputedExample

(

PrimaryKey int PRIMARY KEY,

ComputedCol AS SUSER_NAME()

)

一些复杂表达式映射到多列:

CREATE TABLE SampleTable

(

PriKey int,

FirstName nvarchar(20),

LastName nvarchar(30)

)

GO

CREATE VIEW ConcatView

AS

SELECT PriKey, FirstName + ' ' + LastName AS CombinedName

FROM SampleTable

ConcatView 中的表达式 CombinedName 包含由 FirstName 和 LastName 值串联起来的值。如果在 ConcatView 上定义 INSTEAD OF INSERT 触发器,则对 INSERT 语句如何提供 CombinedName 列值必须有相应的规则,让触发器确定字符串的哪部分应放在 FirstName 列中,哪部分应放在 LastName 列中。如果选择的规则是让 INSERT 语句使用 'first_name;last_name' 规则指定 CombinedName 的值,则该触发器可成功地处理 INSERT:

CREATE TRIGGER InsteadSample on ConcatView

INSTEAD OF INSERT

AS

BEGIN

INSERT INTO SampleTable

SELECT PriKey,

-- Pull out the first name string.

SUBSTRING(

CombinedName,

1,

(CHARINDEX(';', CombinedName) - 1)

),

-- Pull out the last name string.

SUBSTRING(

CombinedName,

(CHARINDEX(';', CombinedName) + 1),

DATALENGTH(CombinedName)

)

FROM inserted

END

需要类似的逻辑来处理本身是简单表达式,但引用的计算列中包含复杂表达式的视图列。

一些视图表达式可转换基表列的值,例如通过执行数学运算或使用列作为函数的参数。在这种情况下,INSTEAD OF INSERT 触发器中的逻辑可采用两种方法:

◆规则可以是:所有 INSERT 语句提供要放在基表中的原始值,而触发器逻辑将该值从 inserted 表移到基表。

◆规则可以是:所有 INSERT 语句提供预期得到的由视图上的 SELECT 返回的值,在这种情况下触发器中的逻辑必须反转此操作。例如:

CREATE TABLE BaseTable

(

PrimaryKey int PRIMARY KEY,

ColumnB int,

ColumnC decimal(19,3)

)

CREATE VIEW SquareView AS

SELECT PrimaryKey, ColumnB,

-- Square the value of ColumnC

SQUARE(ColumnC) AS SquareC

FROM BaseTable

CREATE TRIGGER SquareTrigger ON SquareView

INSTEAD OF INSERT

AS

BEGIN

INSERT INTO BaseTable

SELECT PrimaryKey, ColumnB,

-- Perform logical inverse of function in view.

SQRT(SquareC)

FROM inserted

END

对于某些表达式(如使用加法和减法等数学运算的复杂表达式),用户也许不可能提供特定的值供触发器明确地生成目的基表列的值。例如,如果视图选择列表包含表达式 IntColA + IntColB AS AddedColumns,那么 inserted.AddedColumns 中的值 10 表示什么?10 是3 + 7、2 + 8 还是 5 + 5 的结果?仅从 inserted.AddedColumns 值没有办法得知什么值应放置在 IntColA 和 IntColB 中。

在这些情况下,可对触发器进行编码以使用备用信息源确定基表列中要设置的值。对于具有 INSTEAD OF 触发器的视图,视图选择列表必须包含足够的信息,以生成由触发器修改的基表中所有非空列的值。并不是所有的数据都必须直接来自 inserted 表。在一些情况下,inserted 表中的值可以是触发器用于检索其它基表中相关数据的键值。

【责编:John】

--------------------next---------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值