预览模式: 普通 | 列表

MS Sql Server中update()函数的作用?

今天在触发器中看到

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触发器的工作过程

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.'
101)
ROLLBACK TRANSACTION
END

DECLARE
    
@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 临时表的删除

临时表与一般的表不同,它是保存到tempDb表中。临时表的表名与你所建的表名也不一样,因为他要为不同人的相同操作创建不同的临时表。
1、错误的删除操作:
--错误的临时表删除操作,因为所在数据库不同
IF  EXISTS (SELECT * FROM sysobjects WHERE object_id = OBJECT_ID(N'[dbo].[#tempTable]'AND type in (N'U'))
    
Begin
    
DROP TABLE [dbo].[tempTable]
End
    
--错误的临时表删除操作,因为临时表名已变
if exists (select * from tempdb.dbo.sysobjects where id = object_id(N'[#temptable]'))
Begin
    
drop table #temptable
End

2、正确的删除方式:
--正确的临时表删除操作
if object_id('tempdb..#tempTable'is not null Begin
    
drop table #tempTable
End

SQL存储过程分页算法研究(支持千万级)

1.“俄罗斯存储过程”的改良版

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 文件

<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循环所有表和所有列

[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的分页的优化

关于分页的优化。
我们知道,在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

[阅读全文]