MS Sql Server中update()函数的作用?
作者:周建东 日期:2010-05-24 11:31
今天在触发器中看到
if (update(col1))
begin
print('执行成功');
end
开始没有完全弄明白是怎么回事,后来通过查资料以及实验得出的结论。
在弄清该函数作用前,首先介绍一下触发器(关于触发器介绍内容是在网上摘抄的):
触发器是一种特殊的存储过程,在用户试图对指定的表执行指定的数据修改语句时自动执行。Microsoft® SQL Server™ 允许为任何给定的 INSERT、UPDATE 或 DELETE 语句创建多个触发器。
1、INSERT触发器:可以定义一个无论何时用INSERT语句向表中插入数据时都会执行的触发器。
当触发INSERT触发器时,新的数据行就会被插入到触发器表和inserted表中。inserted表是一个逻辑表,它包含了已经插入的数据行的一个副本。inserted表包含了INSERT语句中已记录的插入动作。inserted表还允许引用由初始化INSERT语句而产生的日志数据。触发器通过检查inserted表来确定是否执行触发器动作或如何执行它。inserted表中的行总是触发器表中一行或多行的副本。
日志记录了所有修改数据的动作(INSERT、UPDATE和DELETE语句),但在事务日志中的信息是不可读的。然而,inserted表允许你引用由INSERT语句引起的日志变化,这样就可以将插入数据与发生的变化进行比较,来验证它们或采取进一步的动作。也可以直接引用插入的数据,而不必将它们存储到变量中。
简单例子:
create trigger trg_insert
o
SQL server 2000中UPDATE触发器的工作过程
作者:周建东 日期:2009-03-31 09:24
UPDATE触发器的工作过程
可将UPDATE语句看成两步操作:即捕获数据前像(before image)的DELETE语句,和捕获数据后像(after image)的INSERT语句。当在定义有触发器的表上执行UPDATE语句时,原始行(前像)被移入到deleted表,更新行(后像)被移入到inserted表。
触发器检查deleted表和inserted表以及被更新的表,来确定是否更新了多行以及如何执行触发器动作。
可以使用IF UPDATE语句定义一个监视指定列的数据更新的触发器。这样,就可以让触发器容易的隔离出特定列的活动。当它检测到指定列已经更新时,触发器就会进一步执行适当的动作,例如发出错误信息指出该列不能更新,或者根据新的更新的列值执行一系列的动作语句。
语法
IF UPDATE (<column_name>)
例1 本例阻止用户修改Employees表中的EmployeeID列。
USE Northwind
GO
CREATE TRIGGER Employee_Update
ON Employees
FOR UPDATE
AS
IF UPDATE (EmployeeID)
BEGIN
RAISERROR ('Transaction cannot be processed.\
***** Employee ID number cannot be modified.', 10, 1)
ROLLBACK TRANSACTION
END
在Sql Server触发器中判断操作是Insert还是Update还是Delete
作者:周建东 日期:2009-03-31 08:50
@IsInsert bit,
@IsUpdate bit,
@IsDelete bit
IF EXISTS(SELECT 1 FROM inserted) AND NOT EXISTS(SELECT 1 FROM deleted)
SET @IsInsert = 1
ELSE
SET @IsInsert = 0
IF EXISTS(SELECT 1 FROM inserted) AND EXISTS(SELECT 1 FROM deleted)
SET @IsUpdate = 1
ELSE
SET @IsUpdate = 0
IF NOT EXISTS(SELECT 1 FROM inserted) AND EXISTS(SELECT 1 FROM deleted)
SET @IsDelete = 1
ELSE
SET @IsDelete = 0
create trigger Update_Del on Table
for
SQL Server 临时表的删除
作者:周建东 日期:2009-02-10 07:57
1、错误的删除操作:
2、正确的删除方式:
SQL存储过程分页算法研究(支持千万级)
作者:周建东 日期:2008-12-27 07:49
CREATE procedure pagination1
(@pagesize int, --页面大小,如每页存储20条记录
@pageindex int --当前页码)
as set nocount on
begin
declare @indextable table(id int identity(1,1),nid int) --定义表变量
declare @PageLowerBound int --定义此页的底码
declare @PageUpperBound int --定义此页的顶码
set @PageLowerBound=(@pageindex-1)*@pagesize
set @PageUpperBound=@PageLowerBound+@pagesize
set rowcount @PageUpperBound
insert into @indextable(nid) select gid from TGongwen where fariqi >dateadd(day,-365,getdate()) order by fariqi desc
select O.gid,O.mid,O.title,O.fadanwei,O.fariqi from TGongwen O,@indextable t where O.gid=t.nid
and t.id>@PageLowerBound and t.id <=@PageUpperBound order by t.id
end
set nocount off
文章中的点评:
以上存储过程运用了SQL SERVER的最新技术――表变量。应该说这个存储过程也是一个非常优秀的分页存储过程。当然,在这个过程中,您也可以把其中的表变量写成临时表:CREATE TABLE #Temp。但很明显,在SQL SERVER中,用临时表是没有用表变量快的。所以笔者刚开始使用这个存储过程时,感觉非常的不错,速度也比原来的ADO的好。但后来,我又发现了比此方法更好的方法。
从感觉上讲,效率不是太高。
2. not in 的方法:
从publish 表中取出第 n 条到第 m 条的记录:
SELECT TOP m-n+1 * FROM publish WHERE
将指定的表/视图中的数据导出为 html 文件
作者:周建东 日期:2008-11-10 13:54
<coolcode lang="sql"> IF OBJECT_ID(N'dbo.p_ExportHtml') IS NOT NULL
DROP PROC dbo.p_ExportHtml;
GO
/*-- == 导出表/视图中的数据为html 文件======================
此存储过程用于将指定的表/视图中的数据导出为 html 文件
由于是使用存储过程, 因此文件目录基于 sql server 服务器
存储过程中会使用xp_cmdshell 调用bcp 来写文件
因此必须打开xp_cmdshell 功能, 可以使用下面的脚本实现
EXEC sp_configure N'show advanced options', 1 RECONFIGURE;
EXEC sp_configure N'xp_cmdshell', 1 RECONFIGURE;
---------------------------------------------------------
-- 调用示例
EXEC dbo.p_ExportHtml
@object_name = N'sys.objects',
@file_name = N'c:\test.html';
---------------------------------------------------------
-- 环境要求
适用于sql server 2005 或者更高的版本
-- ==== 邹建2008.11(引用请保留此信息) =============== */
CREATE PROC dbo.p_ExportHtml
@object_name sysname,
@file_name nvarchar(260),
@title nvarchar(1000) = NULL -- html 标题, 为NULL时使用@object_name
AS
SET NOCOUNT ON;
DECLARE
@sql_field nvarchar(max),
@sql_body nvarchar(max);
SELECT
@sql_field = N'',
@sql_body = N'
SQL 2008循环所有表和所有列
作者:周建东 日期:2008-10-28 07:07
[codes=sql]declare @tblname varchar(200)
declare @object_id int
declare tbl_cursor CURSOR for
select name,object_id from sys.all_objects where type='u'
open tbl_cursor
FETCH NEXT FROM tbl_cursor
INTO @tblname,@object_id
while @@FETCH_STATUS = 0
Begin
declare @str varchar(8000)
declare @selectstr varchar(2000)
set @selectstr=''
set @str='INSERT INTO '+ @tblname +'('
--print @tblname,@object_id
declare @colname varchar(200)
declare col_cursor CURSOR for
select name from sys.columns where object_id=@object_id order by column_id
open col_cursor
FETCH NEXT FROM col_cursor INTO @colname
WHILE @@FETCH_STATUS = 0
BEGIN
set @str=@str+@colname+','
--Print @str
set @selectstr=@selectstr+@colname+','
--Print @colname
FETCH NEXT FROM col_cursor INTO @colname
END
close col_cursor
deallocate col_cursor
set @str=substring(@str,0,len(@str))
set @selectstr=substring(@selectstr,0,len(@selectstr))
set @str=@str+') SELECT ' + @selectstr +' FROM
MySQL的分页的优化
作者:周建东 日期:2008-10-25 07:35
我们知道,在MySQL中分页很简单,直接LIMIT page_no,page_total 就可以了。
可是当记录数慢慢增大时,她就不那么好使了。
这里我们创建摘要表来记录页码和原表之间的关联。
下面为测试数据。
原表:
CREATE TABLE `t_group` (
`id` int(11) NOT NULL auto_increment,
`money` decimal(10,2) NOT NULL,
`user_name` varchar(20) NOT NULL,
`create_time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_combination1` (`user_name`,`money`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
原表总记录数:
mysql> select count(*) from t_group;
+----------+
| count(*) |
+----------+
| 10485760 |
+----------+
1 row in set (0.00 sec)
分页表:
CREATE TABLE `t_group_ids` (
`id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
PRIMARY KEY (`id`,`group_id`),
KEY `idx_id` (`id`),
KEY `idx_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入分页表数据。当然这里如果你的表主键不是ID,那你得自己想办法搞这个分页表的数据了。这个好实现,就不说了。
mysql> insert into t_group_ids select ceil(id/20),id from t_group;
Query








