Google

星期二, 十一月 11, 2008

SQL Server中使用正則表達式

这两天有个需求,需要在数据库中判断字符串的格式,于是从网上搜集了一些资料,整理了一下。

下面这个是一个自定义函数,用户可以调用这个函数判断指定的字符串是否符合正则表达式的规则.
CREATE FUNCTION dbo.find_regular_expression
(
@source varchar(5000), --需要匹配的源字符串
@regexp varchar(1000), --正则表达式
@ignorecase bit = 0 --是否区分大小写,默认为false
)
RETURNS bit --返回结果0-false,1-true
AS
BEGIN

--0(成功)或非零数字(失败),是由 OLE 自动化对象返回的 HRESULT 的整数值。
DECLARE @hr integer

--用于保存返回的对象令牌,以便之后对该对象进行操作
DECLARE @objRegExp integer DECLARE @objMatches integer

--保存结果
DECLARE @results bit

/*
创建 OLE 对象实例,只有 sysadmin 固定服务器角色的成员才能执行 sp_OACreate,并确定机器中有VBScript.RegExp类库
*/
EXEC @hr = sp_OACreate 'VBScript.RegExp', @objRegExp OUTPUT
IF @hr <> 0 BEGIN
SET @results = 0
RETURN @results
END
/*
以下三个分别是设置新建对象的三个属性。下面是'VBScript.RegExp'中常用的属性举例:
Dim regEx,Match,Matches '建立变量。
Set regEx = New RegExp '建立一般表达式。
regEx.Pattern= patrn '设置模式。
regEx.IgnoreCase = True '设置是否区分大小写。
regEx.Global=True '设置全局可用性。
set Matches=regEx.Execute(string) '重复匹配集合
RegExpTest = regEx.Execute(strng) '执行搜索。
for each match in matches '重复匹配集合
RetStr=RetStr &"Match found at position "
RetStr=RetStr&Match.FirstIndex&".Match Value is '"
RetStr=RetStr&Match.Value&"'."&vbCRLF Next
RegExpTest=RetStr

*/
EXEC @hr = sp_OASetProperty @objRegExp, 'Pattern', @regexp
IF @hr <> 0 BEGIN
SET @results = 0
RETURN @results
END
EXEC @hr = sp_OASetProperty @objRegExp, 'Global', false
IF @hr <> 0 BEGIN
SET @results = 0
RETURN @results
END
EXEC @hr = sp_OASetProperty @objRegExp, 'IgnoreCase', @ignorecase
IF @hr <> 0 BEGIN
SET @results = 0
RETURN @results
END
--调用对象方法
EXEC @hr = sp_OAMethod @objRegExp, 'Test', @results OUTPUT, @source
IF @hr <> 0 BEGIN
SET @results = 0
RETURN @results
END
--释放已创建的 OLE 对象
EXEC @hr = sp_OADestroy @objRegExp
IF @hr <> 0 BEGIN
SET @results = 0
RETURN @results
END
RETURN @results
END

下面是一个简单的测试sql语句,可以直接在查询分析器中运行。
DECLARE @intLength AS INTEGER
DECLARE @vchRegularExpression AS VARCHAR(50)
DECLARE @vchSourceString as VARCHAR(50)
DECLARE @vchSourceString2 as VARCHAR(50)
DECLARE @bitHasNoSpecialCharacters as BIT

-- 初始化变量
SET @vchSourceString = 'Test one This is a test!!'
SET @vchSourceString2 = 'Test two This is a test'

-- 我们的正则表达式应该类似于
-- [a-zA-Z ]{}
-- 如: [a-zA-Z ]{10} ... 一个十字符的字符串

-- 获得字符串长度
SET @intLength = LEN(@vchSourceString)

-- 设置完整的正则表达式
SET @vchRegularExpression = '[a-zA-Z ]{' + CAST(@intLength as varchar) + '}'

-- 是否有任何特殊字符
SET @bitHasNoSpecialCharacters = dbo.find_regular_expression(@vchSourceString, @vchRegularExpression,0)

PRINT @vchSourceString
IF @bitHasNoSpecialCharacters = 1 BEGIN
PRINT 'No special characters.'
END ELSE BEGIN
PRINT 'Special characters found.'
END

PRINT '**************'

-- 获得字符串长度
SET @intLength = LEN(@vchSourceString2)

-- 设置完整的正则表达式
SET @vchRegularExpression = '[a-zA-Z ]{' + CAST(@intLength as varchar) + '}'

-- 是否有任何特殊字符
SET @bitHasNoSpecialCharacters = dbo.find_regular_expression(@vchSourceString2, @vchRegularExpression,0)

PRINT @vchSourceString2
IF @bitHasNoSpecialCharacters = 1 BEGIN
PRINT 'No special characters.'
END ELSE BEGIN
PRINT 'Special characters found.'
END
GO

http://blog.csdn.net/weir55/archive/2008/04/28/2337096.aspx

标签: , ,

星期二, 八月 19, 2008

高速全文检索引擎Sphinx安装指南及下载

Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索

http://srsman.com/2008/08/sphinx/

标签: , , , ,

星期四, 七月 03, 2008

SQL导出数据到EXCEL文件

create excel xls from t-sql
---------------------------------------------------------------------------
-- create xls script dal - 04/24/2003
--
-- designed for agent scheduling, turn on "append output for step history"
--
-- search for %%% to find adjustable constants and other options
--
-- uses ole for ado and ole db to create the xls file if it does not exist
-- linked server requires the xls to exist before creation
-- uses ole ado to create the xls worksheet for use as a table by t-sql
-- uses linked server to allow t-sql access to xls table
-- uses t-sql to populate te xls worksheet, very fast
--
print begin createxls script at +rtrim(convert(varchar(24),getdate(),121))+
print
go

set nocount on
declare @conn int -- ado connection object to create xls
, @hr int -- ole return value
, @src varchar(255) -- ole error source
, @desc varchar(255) -- ole error description
, @path varchar(255) -- drive or unc path for xls
, @connect varchar(255) -- ole db connection string for jet 4 excel isam
, @wks_created bit -- whether the xls worksheet exists
, @wks_name varchar(128) -- name of the xls worksheet (table)
, @servername nvarchar(128) -- linked server name for xls
, @ddl varchar(8000) -- jet4 ddl for the xls wks table creation
, @sql varchar(8000) -- insert into xls t-sql
, @recs int -- number of records added to xls
, @log bit -- whether to log process detail

-- init variables
select @recs = 0
-- %%% 1 = verbose output detail, helps find problems, 0 = minimal output detail
, @log = 1
-- %%% assign the unc or path and name for the xls file, requires read/write access
-- must be accessable from server via sql server service account
-- & sql server agent service account, if scheduled
set @path = c:\temp\test_+convert(varchar(10),getdate(),112)+.xls
-- assign the ado connection string for the xls creation
set @connect = provider=microsoft.jet.oledb.4.0;data source=+@path+;extended properties=excel 8.0
-- %%% assign the linked server name for the xls population
set @servername = excel_test
-- %%% rename table as required, this will also be the xls worksheet name
set @wks_name = people
-- %%% table creation ddl, uses jet4 syntax,
-- text data type = varchar(255) when accessed from t-sql
set @ddl = create table +@wks_name+ (ssn text, name text, phone text)
-- %%% t-sql for table population, note the 4 part naming required by jet4 ole db
-- insert into select, insert into values, and exec sp types are supported
-- linked server does not support select into types
set @sql = insert into +@servername+...+@wks_name+ (ssn, name, phone)
set @sql = @sql+select au_id as ssn
set @sql = @sql+, ltrim(rtrim(isnull(au_fname,)+ +isnull(au_lname,))) as name
set @sql = @sql+, phone as phone
set @sql = @sql+from pubs.dbo.authors

if @log = 1 print created ole adodb.connection object
-- create the conn object
exec @hr = sp_oacreate adodb.connection, @conn out
if @hr <> 0 -- have to use <> as ole / ado can return negative error numbers
begin
-- return ole error
exec sp_oageterrorinfo @conn, @src out, @desc out
select error=convert(varbinary(4),@hr), source=@src, description=@desc
return
end

if @log = 1 print char(9)+assigned connectionstring property
-- set a the conn objects connectionstring property
-- work-around for error using a variable parameter on the open method
exec @hr = sp_oasetproperty @conn, connectionstring, @connect
if @hr <> 0
begin
-- return ole error
exec sp_oageterrorinfo @conn, @src out, @desc out
select error=convert(varbinary(4),@hr), source=@src, description=@desc
return
end

if @log = 1 print char(9)+open connection to xls, for file create or append
-- call the open method to create the xls if it does not exist, cant use parameters
exec @hr = sp_oamethod @conn, open
if @hr <> 0
begin
-- return ole error
exec sp_oageterrorinfo @conn, @src out, @desc out
select error=convert(varbinary(4),@hr), source=@src, description=@desc
return
end

-- %%% this section could be repeated for multiple worksheets (tables)
if @log = 1 print char(9)+execute ddl to create +@wks_name+ worksheet
-- call the execute method to create the work sheet with the @wks_name caption,
-- which is also used as a table reference in t-sql
-- neat way to define column data types in excel worksheet
-- sometimes converting to text is the only work-around for excels general
-- cell formatting, even though the cell contains text, excel tries to format
-- it in a "smart" way, i have even had to use the single quote appended as the
-- 1st character in t-sql to force excel to leave it alone
exec @hr = sp_oamethod @conn, execute, null, @ddl, null, 129 -- adcmdtext + adexecutenorecords
-- 0x80040e14 for table exists in ado
if @hr = 0x80040e14
-- kludge, skip 0x80042732 for ado optional parameters (null) in sql7
or @hr = 0x80042732
begin
-- trap these ole errors
if @hr = 0x80040e14
begin
print char(9)++@wks_name+ worksheet exists for append
set @wks_created = 0
end
set @hr = 0 -- ignore these errors
end
if @hr <> 0
begin
-- return ole error
exec sp_oageterrorinfo @conn, @src out, @desc out
select error=convert(varbinary(4),@hr), source=@src, description=@desc
return
end

if @log = 1 print destroyed ole adodb.connection object
-- destroy the conn object, +++ important to not leak memory +++
exec @hr = sp_oadestroy @conn
if @hr <> 0
begin
-- return ole error
exec sp_oageterrorinfo @conn, @src out, @desc out
select error=convert(varbinary(4),@hr), source=@src, description=@desc
return
end

-- linked server allows t-sql to access the xls worksheet (table)
-- this must be performed after the ado stuff as the xls must exist
-- and contain the schema for the table, or worksheet
if not exists(select srvname from master.dbo.sysservers where srvname = @servername)
begin
if @log = 1 print created linked server +@servername+ and login
exec sp_addlinkedserver @server = @servername
, @srvproduct = microsoft excel workbook
, @provider = microsoft.jet.oledb.4.0
, @datasrc = @path
, @provstr = excel 8.0
-- no login name or password are required to connect to the jet4 isam linked server
exec sp_addlinkedsrvlogin @servername, false
end

-- have to exec the sql, otherwise the sql is evaluated
-- for the linked server before it exists
exec (@sql)
print char(9)+populated +@wks_name+ table with +convert(varchar,@@rowcount)+ rows

-- %%% optional you may leave the linked server for other xls operations
-- remember that the linked server will not create the xls, so remove it
-- when you are done with it, especially if you delete or move the file
if exists(select srvname from master.dbo.sysservers where srvname = @servername)
begin
if @log = 1 print deleted linked server +@servername+ and login
exec sp_dropserver @servername, droplogins
end
go

set nocount off
print
print finished createxls script at +rtrim(convert(varchar(24),getdate(),121))+
go

目的
set @path = c:\temp\test_+convert(varchar(10),getdate(),112)+.xls


set @sql = insert into +@servername+...+@wks_name+ (ssn, name, phone)
set @sql = @sql+select au_id as ssn
set @sql = @sql+, ltrim(rtrim(isnull(au_fname,)+ +isnull(au_lname,))) as name
set @sql = @sql+, phone as phone
set @sql = @sql+from pubs.dbo.authors
http://www.west263.com/www/info/27281-1.htm

标签: , , ,

星期一, 四月 28, 2008

什么是 Kohana? Kohana 与 CodeIgniter 的区别?

作者:沧蓝 / Fred Wu

Kohana 是一款基于 CodeIgniter 的 PHP5 框架,其与 CI 最大的区别便是 Kohana 完全采用 PHP5。

2007 年 6 月 1 日,CI 社区用户 Todd Wilson (Tido) 发布了 BlueFlame 1.0 的帖子。BlueFlame 1.0 正式发布,团队成员有九人,其中包括 Todd(原团队 lead developer)、现在 Kohana 的 lead developer、以及本人。该发布贴引起了 CI 社区用户的广泛关注。然而由于 BlueFlame 团队事前没有与 CodeIgniter 团队进行沟通,导致一些理解上的小插曲,包括 Rick (CI 的祖父)要求 BlueFlame 团队停止使用 CI 的社区资源来发布 BlueFlame 相关的信息,以及对 BlueFlame 源代码中的授权部分表示疑义。

最终通过 BlueFlame 与 CodeIgniter 团队的协调沟通,双方的小小误解很快便被解化。Rick 在此期间提到 BlueFlame 名称的潜在版权问题,于是 BlueFlame 几天后便正式更名为 Kohana,并注册了现在的官方网站:kohanaphp.com

在 BlueFlame 1.0 之后,Kohana 团队一直没有发布新的版本,之后整个项目一度处于僵化期。尽管如此,trac 上还是有更新进度。在 Todd Wilson “消失”了一阵子后,成员之一 Woody Gilk (Shadow Hand) 接下重任,担当团队 leader。

之后 Woody 联络本人,希望本人承担 Kohana 官方网站以及 logo 的设计制作。论坛上仍然可以找到当时我发的帖子(内有网站以及 logo 的草案)。可惜由于时间的因素,我最终没有将设计草案转化为 HTML。可喜的是,Geert De Deckere 之后设计了一个相当出色的方案,这也就是大家现在所见到的 Kohana 的官方网站。 :)

2007 年 11 月,经过了团队成员以及社区用户的努力,Kohana 终于发布了 2.0 版本。

下面我来翻译一下 Wikipedia 对于 Kohana 的介绍。

历史

Kohana 是基于 CodeIgniter PHP 框架开发的。

开发 Kohana 最主要的原因是 CI 对于 bug 的修复和处理用户提交的建议所需的时间过长。许多 bug 在用户报告后很久才会纳入到新版本中,甚至一些 bug 一直没有被纳入。另外,由于 EllisLab 是 CodeIgniter 唯一开发者,部分用户对于框架的开放性产生异议,他们希望框架可以更自由开放,从而使社区对框架的发展产生一定的影响。

Kohana 与 CodeIgniter 的区别


  • 严谨的 PHP5 面向对象编程。优势:可见性保护、自动类装载、超载、接口类、抽象类以及单件类。
  • 延续 CodeIgniter 的设计模式。CodeIgniter 的用户能迅速的理解 Kohana 的架构和设计模式。
  • 社区向,而非商业向。Kohana 是一款基于社区的作品。Kohana 的开发者们来自世界各地,有着各自的天赋。这使得开发速度得以提高,并在短时间内提供bug修复以及反馈用户提出的建议。
  • GET、POST、COOKIE 以及 SESSION 数组得到改进。Kohana 不对全局数据做读取限制,但依旧提供与 CodeIgniter 相同的数据过滤以及 XSS 防护。
  • 层叠式资源、模块以及类继承。控制器、数据模型、库、助手以及视图均能够在系统中的任何地方进行载入。程序的配置选项可被继承或覆盖。
  • 无命名空间的冲突。类均添加了如“_Controller”之类的后缀,从而使得用户的控制器和数据模型可被同时同地装载。
  • 真正的自动类装载。这包括库、控制器、数据模型以及助手。与 CodeIgniter 不同,Kohana 的自动装载是真正意义上的动态装载,而并非预先装载。
  • 助手为静态类,而非函数。例如,在 CI 中使用的 form_open(),在 Kohana 中为 form::open()。
  • 库驱动以及 API 的一致性。库能够使用不同的驱动来处理不同的外部 API。例如,session 的储存有数据库、cookie 和 native 几种,但它们均使用相同的接口。这使得库可以不断的添加新的驱动,但不会影响到 API 的一致性。
  • 强大的事件处理器。Kohana 的事件可被动态的添加、替换或删除。这使得用户能在 Kohana 执行的过程中动态做更改,而不影响原有的系统代码。


特性


  • 高安全性
  • 轻量级代码
  • 学习周期短
  • MVC 设计模式
  • 100% UTF-8 兼容
  • 松弛耦合架构
  • 易扩展性


技术


  • 严谨的 PHP5 面向对象编程
  • 用 SQL 助手实现简单的数据库抽象层
  • 多 session 驱动(native、数据库、cookie)
  • 动态事件处理器


==============================

最后更新:2007 年 12 月 03 日

http://codeigniter.org.cn/forums/thread-91-1-1.html

标签: , , , , , ,

星期三, 四月 09, 2008

跟我学SQL:(七)从子表里删除数据

在这篇文章里我要描述一下如何从表格里删除列,要删除的这些列同时还要依赖于其他表格的标准。要解决这个问题就需要一个很聪明而且完全遵守SQL92子查询声明的应用程序。
我必须提醒读者的是,尽管查询可能会遵守SQL的标准,但是众多的数据库生产商会以不同的句法支持实现SQL。以下这个解决方案应该适合于大多数数据库; 但是,如果你的结果有出入,就还是应该查看一下文档。同时,由于这个查询要处理DELETE声明,所以你应该在将其应用于真实的生产环境以前在实验数据上 进行测试。

需要更多的背景信息?
查看这些文章就能快速上路:
《SQL基础I查数据查询》涉及到了DELETE查询的使用。
《使用SQL子选项来合并查询》说明子选项查询能够减少对数据库请求的数量,并提供了例子。
《SQL基础:查询多个表》提供了更多关于子选项的信息,还讲到了使用单个查询就能访问多个表格的多种其他方法。

宠物店的例子
要解释如何进行这种类型的列删除,我会使用如下这个数据库的表格,该数据库叫做PetStore,并包含有清单(inventory)信息。在叫做“品种 (breed)”的表A里,我存储有每种动物的信息和宠物店库存的信息。在叫做“清单”的表B里,包含有商店里特定动物的信息。

在这个例子里,我们先假设商店把整窝Shitzu小狗都卖完了。我可以使用breed表格里的breed_id字段来删除Shitzu清单里的所有项目,就像这样:

DELETE FROM inventory WHERE breed_id IN
(SELECT breed_id FROM breed WHERE breed_name = ‘Shitzu’);

首先,我要指定需要删除记录的表格,在这里是清单表格。然后再将识别字段breed_id同子选项子句的结果反复比对。我知道要找的是Shitzus,所以就能直接删掉他们,而不用再在单独的请求里查询breed_id。

我必须要警告你的是,以这种方式使用DELETE声明是危险的,只有在你对数据库的结构很熟悉的情况下才能使用这些声明。DELETE查询会从受影响的表 格里删除掉全部列,你应该知道这对你所管理着的数据意味着什么。有个好办法是使用SELETE *这个短语替代DELETE关键字来对DELETE声明的子查询结果进行测试,这样就能保证结果里含有你要删除的所有东西,就像这样:

SELECT * FROM inventory WHERE breed_id IN
(SELECT breed_id FROM breed WHERE breed_name = ‘Shitzu’);

DELETE和JOIN联用
有人问到了解决这个问题另一个可能的办法:把JOIN子句和DELETE声明联合使用。由于以前没有使用过这种方法,我就研究了一下,发现SQL Server的文档声明支持这个方法,尽管它不符合SQL92。在经过测试和询问各种数据库平台的老手之后,我发现把DELETE和JOIN声明联合使用 在我测试过的任何平台上都行不通。

从多个表格里一次删除
以上的解决方案还没有解释如何使用父表从多个子表里删除信息。但是SQL92规范里没有提供完成这项任务的标准解决方案。

DELETE的声明不能把多个表格作为一个参数接受。作为一个具有破坏性的查询,这能保证在命令要被执行的地方不会出现歧义。此外,这个限制防止了在单个 声明内将AND和多个子查询联用。如果测试SELECT声明的结果用以检查DELETE查询将要影响到的是哪些数据,你会发现SELECT会返回多个表格 的清单,DELETE不会影响到的多个子查询不在其中。

有很多可能的方法能够满足你的需求,例如在表格里创建一个字段,用以指明该项目是否为活动的。或者,你可以使用一些数据库里的预存程序在每个所需的DELETE查询里迭代。

http://bbs.jcwcn.com/thread-7099-1-11.html

标签:

星期一, 四月 07, 2008

Oracle/MS SQL Server的数据库多表关联更新UPDATE与多表更新

一条Update更新语句是不能更新多张表的,除非使用触发器隐含更新。而表的更新操作中,在很多情况下需要在表达式中引用要更新的表以外的数据。我们先来讨论根据其他表数据更新你要更新的表


一、MS SQL Server 多表关联更新

sql server提供了update的from 子句,可以将要更新的表与其它的数据源连接起来。虽然只能对一个表进行更新,但是通过将要更新的表与其它的数据源连接起来,就可以在update的表达式 中引用要更新的表以外的其它数据。
一般形式:

update A SET 字段1=B表字段表达式, 字段2=B表字段表达式 from B WHERE 逻辑表达式

例如:

UPDATE dbo.Table2
SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
FROM dbo.Table2
INNER JOIN dbo.Table1
ON (dbo.Table2.ColA = dbo.Table1.ColA);

实际更新的操作是在要更新的表上进行的,而不是在from子句所形成的新的结果集上进行的

二、Oracle 多表关联更新

Oracle没有update from语法,可以通过两种实现方式:

1、利用子查询:
update A
SET 字段1=(select 字段表达式 from B WHERE ...),
字段2=(select 字段表达式 from B WHERE ...)
WHERE 逻辑表达式

UPDATE多个字段两种写法:


写法一:

UPDATE table_1 a
SET col_x1 = (SELECT b.col_y1, b.col_y2 FROM table_2 b WHERE b.col_n = a.col_m),
col_x2 = (SELECT b.col_y2 FROM table_2 b WHERE b.col_n = a.col_m)
WHERE EXISTS (SELECT * FROM table_2 b WHERE b.col_n = a.col_m)



UPDATE table_1 a
SET col_x1 = (SELECT b.col_y1, b.col_y2 FROM table_2 b WHERE b.col_n = a.col_m),
col_x2 = (SELECT b.col_y2 FROM table_2 b WHERE b.col_n = a.col_m)
WHERE a.col_m=(SELECT b.col_n FROM table_2 b WHERE b.col_n = a.col_m)


写法二:

UPDATE table_1 a
SET (col_x1, col_x2) = (SELECT b.col_y1, b.col_y2 FROM table_2 b WHERE b.col_n = a.col_m)
WHERE EXISTS (SELECT * FROM table_2 b WHERE b.col_n = a.col_m);



UPDATE table_1 a
SET (col_x1, col_x2) = (SELECT b.col_y1, b.col_y2 FROM table_2 b WHERE b.col_n = a.col_m)
WHERE a.col_m=(SELECT b.col_n FROM table_2 b WHERE b.col_n = a.col_m)

注意:

1. 对于子查询的值只能是一个唯一值,不能是多值。
2. 子查询在绝大多数情况下,最后面的where EXISTS子句是重要的,否则将得到错误的结果。且where EXISTS子句可用另一方法代替,如上。

2、利用视图:

UPDATE (SELECT A.NAME ANAME,B.NAME BNAME FROM A,B WHERE A.ID=B.ID)
SET ANAME=BNAME;

注意:

1. 对于视图更新的限制:
如果视图基于多个表的连接,那么用户更新(update)视图记录的能力将受到限制。除非update只涉及一个表且视图列中包含了被更新的表的整个主键,否则不能更新视图的基表。


另外,Oracle中的Delete的from子句也没有多表联接的功能,只能通过子查询的方式来做:
delete from 表A where exists (select * from 表B where 表A.empid=表B.empid)
delete from 表A where 表A.empid in (select empid from 表B)

三、oracle视图多表更新

在oracle中通常如果视图的数据源来自单表则该视图可以进行更新。而如果视图数据源来自两个以上表时这个视图是不可更新的。但有时候为了操作的方便我们更希望能够对多表视图也进行更新。

这时候我们可以通过建立更新触发器来替代该视图原有更新以达到多表更新的效果

例如:

3.1 创建测试数据表
--===================================================
--创建测试表
--===================================================
Drop Table t1;
Drop Table t2;
create table t1
( t11 numeric(28),t12 varchar2(20));
create table t2
( t11 numeric(28),t22 varchar2(20));

3.2 多表视图范例
--===================================================
--创建测试视图
--===================================================
create Or Replace view t as
select T1.t11 f1 ,T1.t12 f2 ,T2.t22 f3
from T1,T2
Where T1.t11=T2.t11;

3.3 多表视图触发器范例
--===================================================
--创建视图的替代触发器
--===================================================
Create Or Replace Trigger Trg_InsUpdDel_t
Instead Of Insert or update or delete
on t
for each row
Declare
begin
If Inserting Then
Insert Into t1 (t11,t12) Values (:New.f1,:New.f2);
Insert Into t2 (t11,t22) Values (:New.f1,:New.f3);
elsif Updating Then
Update t1 set t11=:New.f1,t12=:New.f2 where t11=:New.f1;
Update t2 set t11=:New.f1,t22=:New.f3 where t11=:New.f1;
elsif Deleting then
Delete from t1 where t11=:Old.f1;
Delete from t2 where t11=:Old.f1;
End if;
end;
如此即实现多表可更新视图的定义工作 。

但要注意当视图进行重新编译的时候这个触发器会失效需要重建。


http://hi.baidu.com/suofang/blog/item/249c067b40c8def00ad187aa.html

标签: , ,

星期四, 三月 27, 2008

SQL Having

今天发现一个特别好的SQL语句学习的站点:

那我们如何对函数产生的值来设定条件呢?举例来说,我们可能只需要知道哪些店的营业额有超过 $1,500。在这个情况下,我们不能使用 WHERE 的指令。 那要怎么办呢?很幸运地,SQL 有提供一个 HAVING 的指令,而 我们就可以用这个指令来达到这个目标。 HAVING 子句通常是在一个 SQL 句子的最后。一个含有 HAVING 子句的 SQL 并不一定要包含 GROUP BY 子句。HAVING 的语法如下:

SELECT "栏位1", SUM("栏位2")
FROM "表格名"
GROUP BY "栏位1"
HAVING (函数条件)

请读者注意: GROUP BY 子句并不是一定需要的。

在我们Store_Information 表格这个例子中,

Store_Information 表格

store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999

我们打入,

SELECT store_name, SUM(sales)
FROM Store_Information
GROUP BY store_name
HAVING SUM(sales) > 1500

结果:

store_nameSUM(Sales)
Los Angeles
$1800

http://sql.1keydata.com/cn/sql-having.php

标签:

辽ICP备05003652号
流风洄雪听天籁,轻云蔽日看落花

Powered by Blogger