仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 736|回复: 7
打印 上一主题 下一主题

[学习教程] MYSQL网页编程之制止在 SQL Server 中自觉地寻求一句处...

[复制链接]
活着的死人 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 22:30:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
采用DBaaS解决方案,他们也可以使用同大企业一样的技术。在大型组织中,DBaaS可以提供部门级解决MySQL学习教程,而无需IT部门和采购部门的介入,提供更快和更容易的方法来实现小型解决方案。server成绩形貌
营业需求以下:
有表A和表B,这两个表布局分歧,为分歧的营业服务,如今要写一个存储历程,存储历程承受一个参数,当参数为0时,查询表A,参数为1时,查询表B。

A、一样平常的处置办法
IF@Flag=0
SELECT*FROMdbo.A
ELSEIF@Flag=1
SELECT*FROMdbo.B

B、一句的处置办法
SELECT*FROMdbo.A
WHERE@Flag=0
UNIONALL
SELECT*FROMdbo.B
WHERE@Flag=1

剖析
从语句的简便性来看,办法B具有技能性,它们二者之间,事实那一个更好呢?你大概会从功能下去评价,以决意究竟用那一种。纯真从语句下去看,仿佛二者的效力差未几,上面经由过程数据测试来反应了局仿佛和想像的一样

创建测试情况(注,此测试情况是为几个主题服务的,因而布局看起来有些奇异)
USEtempdb
GO

SETNOCOUNTON
--======================================
--创立测试情况
--======================================
RAISERROR(创立测试情况,10,1)WITHNOWAIT
--TableA
CREATETABLE[dbo].A(
[TranNumber][int]IDENTITY(1,1)NOTNULL,
[INVNO][char](8)NOTNULL,
[ITEM][char](15)NULLDEFAULT(),
PRIMARYKEY([TranNumber])
)

CREATEINDEX[indexONinvno]ON[dbo].A([INVNO])
CREATEINDEX[indexOnitem]ON[dbo].A([ITEM])
CREATEINDEX[indexONiteminnvo]ON[dbo].A([INVNO],[ITEM])
GO

--TableB
CREATETABLE[dbo].B(
[ItemNumber][char](15)NOTNULLDEFAULT(),
[CompanyCode][char](4)NOTNULL,
[OwnerCompanyCode][char](4)NULL,
PRIMARYKEY([ItemNumber],[CompanyCode])
)

CREATEINDEX[ItemNumber]ON[dbo].B([ItemNumber])
CREATEINDEX[CompanyCode]ON[dbo].B([CompanyCode])
CREATEINDEX[OwnerCompanyCode]ON[dbo].B([OwnerCompanyCode])
GO

--======================================
--天生测试数据
--======================================
RAISERROR(天生测试数据,10,1)WITHNOWAIT
INSERT[dbo].A([INVNO],[ITEM])
SELECTLEFT(NEWID(),8),RIGHT(NEWID(),15)
FROMsyscolumnsA,syscolumnsB

INSERT[dbo].B([ItemNumber],[CompanyCode],[OwnerCompanyCode])
SELECTRIGHT(NEWID(),15),LEFT(NEWID(),4),LEFT(NEWID(),4)
FROMsyscolumnsA,syscolumnsB
GO

举行功能测试
DECLARE@aint
SET@a=1

DECLARE@tTABLE(
idintIDENTITY,
aint,bint)
DECLARE@dtdatetime,@loopint,@idint
SET@loop=0
WHILE@loop<5
BEGIN
SET@loop=@loop+1
RAISERROR(test%d,10,1,@loop)WITHNOWAIT
SET@dt=GETDATE()
SELECT[ITEM]FROMA
WHERE@a=0
AND[ITEM]<A
UNIONALL
SELECT[ItemNumber]FROMB
WHERE@a=1
AND[ItemNumber]<A
INSERT@t(a)VALUES(DATEDIFF(ms,@dt,GETDATE()))
SELECT@id=SCOPE_IDENTITY(),@dt=GETDATE()
IF@a=0
SELECT[ITEM]FROMA
WHERE[ITEM]<A
ELSEIF@a=1
SELECT[ItemNumber]FROMB
WHERE[ItemNumber]<A
UPDATE@tSETb=DATEDIFF(ms,@dt,GETDATE())
WHEREid=@id
END
SELECT*FROM@t
UNIONALL
SELECTNULL,SUM(a),SUM(b)FROM@t

功能测试了局
idab
-----------------
134102063
217031656
317631656
418001793
516431856
NULL103199024

从了局看,二者的功能差别很小,以是二者从功能上对照,能够视为没有差别

成绩地点
固然在功能上,二者没有甚么差别,但另外一个成绩大概你历来没有思索过,那就是对表的会见的成绩,在办法A中,一定只会会见到一个表;而在办法B中,情形仍是云云吗?谜底是不是定的,办法B一直会扫描两个表。而如许的潜台词是,即便在我的查询中,只会用到A表,但假如B表被下了锁的话,全部查询就会被堵塞,而办法A不会。
为了证实这个成绩,我们再做上面的测试

BLOCK的测试―为表A加锁(查询窗口A)
BEGINTRAN
UPDATEASET[ITEM]=RIGHT(NEWID(),4)
WHERE[ITEM]BETWEEN9ANDA
--ROLLBACKTRAN--不回滚事件,让锁一向坚持

BLOCK的测试―测试查询办法A(查询窗口B)
--runquerywindows2
DECLARE@aint
SET@a=1

IF@a=0
SELECT[TranNumber]FROMA
WHERE[ITEM]<A
ELSEIF@a=1
SELECT[ItemNumber]FROMB
WHERE[ItemNumber]<A

BLOCK的测试―测试查询办法B(查询窗口C)
--runquerywindows3
DECLARE@aint
SET@a=1

SELECT[ITEM]FROMA
WHERE@a=0
AND[ITEM]<A
UNIONALL
SELECT[ItemNumber]FROMB
WHERE@a=1
AND[ItemNumber]<A

了局
你会看到,查询窗口B中的查询会实时地完成,而查询窗口C的查询会一向守候,你能够经由过程实行存储历程sp_who2,检察以后的BLOCK情况来断定查询窗口C的查询是不是被查询窗口A的查询BLOCK住

结论
不要利用查询办法B,它看起来很棒,实践的了局便是会增添被BLOCK的时机



Trackback:http://tb.blog.csdn.net/TrackBack.aspx?PostId=787074
[点击此处保藏本文]宣布于2006年06月10日20:55:00

沧海笑一声宣布于2006-06-1100:37:00IP:221.221.210.*
精炼!
感激分享!

hmj宣布于2006-06-1113:18:00IP:222.95.184.*
又学到了新器材!

cyz1980宣布于2006-06-1208:15:00IP:222.76.2.*
邹年老:
你好,以上形貌的成绩我也有碰着,对我的启发也很年夜,感谢。但在实践中,有些仍是要“一挥而就”的。好比以下成绩(代码对照长,正由于如许,才对照有深入的体味,哈哈。。),了解不到位的中央看邹年老指导一下:
第一种办法(作视图用,便于数据库迁徙,便于Access等疾速挪用,合用性广):
declare@monthdatetime
set@month=2005-4-1
select@monthas月份,dpname1as部门,isnull(开户人次,0)as开户人次,isnull(开户后第一次存款额,0)as开户后第一次存款额,isnull(消耗额,0)as消耗额,
isnull(消耗次数,0)as消耗次数,isnull(存存款额,0)as存存款额,isnull(存存款次数,0)as存存款次数,isnull(卡余额总额,0)as卡余额总额
from(selectdistinctdpcode1,dpname1fromT_Department)Departmentleftouterjoin(SELECTDpCode1,kh_month,COUNT(*)AS开户人次,SUM(in_out_fare)
AS开户后第一次存款额
FROM(SELECTdep.DpCode1,RTRIM(CAST(YEAR(T_Customers.OpenDt)ASchar))
+-+RTRIM(CAST(MONTH(T_Customers.OpenDt)ASchar))
+-+RTRIM(DAY(0))ASkh_month,min_in_out_fare.in_out_fare
FROMT_CustomersINNERJOIN
(SELECTDpCode1+DpCode2+DpCode3ASdpcode,DpCode1
FROMT_Department)depON
T_Customers.Account=dep.dpcodeleftouterJOIN
(SELECTmin_opcount.CustomerID,
T_CashRec.InFare-T_CashRec.OutFarein_out_fare
FROM(SELECTCustomerID,MIN(OpCount)ASmin_opcount
FROMT_CashRec
GROUPBYCustomerID)min_opcountINNERJOIN
T_CashRecON
min_opcount.CustomerID=T_CashRec.CustomerIDAND
min_opcount.min_opcount=T_CashRec.OpCount)min_in_out_fareON
min_in_out_fare.CustomerID=T_Customers.CustomerID)
一级单元月开户明细
GROUPBYDpCode1,kh_monthhavingkh_month=@month/*一级单元月开户汇总*/
)khonkh.dpcode1=Department.dpcode1leftouterjoin(SELECTDpCode1,xf_month,SUM(OpFare)AS消耗额,count(*)as消耗次数
FROM(SELECTdep.DpCode1,RTRIM(CAST(YEAR(consumerec.OpDt)ASchar))
+-+RTRIM(CAST(MONTH(consumerec.OpDt)ASchar))+-+RTRIM(DAY(0))
ASxf_month,consumerec.OpFare
FROMT_ConsumeRecconsumerecINNERJOIN
T_CustomersON
consumerec.CustomerID=T_Customers.CustomerIDINNERJOIN
(SELECTDpCode1+DpCode2+DpCode3ASdpcode,DpCode1
FROMT_Department)depONT_Customers.Account=dep.dpcode)
一级单元月消耗明细
GROUPBYDpCode1,xf_monthhavingxf_month=@month/*一级单元月消耗汇总*/
)xfonxf.dpcode1=Department.dpcode1leftouterjoin(SELECTDpCode1,cqk_month,SUM(inFare-outFare)AS存存款额,count(*)as存存款次数
FROM(SELECTdep.DpCode1,RTRIM(CAST(YEAR(consumerec.cashdt)ASchar))
+-+RTRIM(CAST(MONTH(consumerec.cashdt)ASchar))
+-+RTRIM(DAY(0))AScqk_month,consumerec.inFare,
consumerec.outFare
FROMT_CashRecconsumerecINNERJOIN
T_CustomersON
consumerec.CustomerID=T_Customers.CustomerIDINNERJOIN
(SELECTDpCode1+DpCode2+DpCode3ASdpcode,DpCode1
FROMT_Department)depONT_Customers.Account=dep.dpcode)
一级单元月存存款明细
GROUPBYDpCode1,cqk_monthhavingcqk_month=@month/*一级单元月存存款汇总*/
)cqoncq.dpcode1=Department.dpcode1leftouterjoin(SELECTdep.DpCode1,sum(id_MaxO.OddFare)as卡余额总额
FROM(SELECTid_m_maxC.customerid,id_c_o.OddFare
FROM(SELECTcustomerid,MAX(OpCount)ASmax_opcount
FROM(SELECTCustomerID,OpCount,RTRIM(CAST(YEAR(Dt)ASchar))
+-+RTRIM(CAST(MONTH(Dt)ASchar))+-+RTRIM(DAY(0))
ASmonth
FROM(SELECTCustomerID,OpCount,OpDtASdt
FROMT_ConsumeRec
UNIONALL
SELECTCustomerID,OpCount,cashDtASdt
FROMT_cashRec
UNIONALL
SELECTCustomerID,OpCount,putoutDtASdt
FROMT_subsidyputout)id_c_d)id_c_mwheremonth<=@month/*月份参数*/
GROUPBYcustomerid
)id_m_maxCINNERJOIN
(SELECTCustomerID,OpCount,OddFare
FROM(SELECTCustomerID,OpCount,OddFare
FROMT_ConsumeRec
UNIONALL
SELECTCustomerID,OpCount,OddFare
FROMT_cashRec
UNIONALL
SELECTCustomerID,OpCount,OddFare
FROMT_subsidyputout)Lid_c_o)id_c_oON
id_c_o.CustomerID=id_m_maxC.customeridAND
id_c_o.OpCount=id_m_maxC.max_opcount)id_MaxOINNERJOIN
T_CustomersONid_MaxO.customerid=T_Customers.CustomerIDINNERJOIN
(SELECTDpCode1+DpCode2+DpCode3ASdpcode,DpCode1
FROMT_Department)depONT_Customers.Account=dep.dpcode/*一级单元在某月份的卡余额明细*/
groupbydep.DpCode1/*一级单元在某月份的卡余额汇总*/)kyeonkye.dpcode1=Department.dpcode1
实行后的示例数据:
月份部门开户人次开户后第一次存款额消耗额消耗次数存存款额存存款次数卡余额总额
2005-4-1职工卡4¥2,400.00¥7,728.291054¥531,369.401112¥523,937.84
2005-4-1职工卡20¥0.00¥0.000¥0.000¥0.00
2005-4-1外单元职员100¥620.00¥0.000¥620.004¥620.00
2005-4-1挂帐卡0¥0.00¥0.000¥0.000¥0.00
2005-4-1现金卡2¥0.00¥0.000¥0.000¥0.00
2005-4-1扣头卡56¥16,500.00¥984.40152¥16,500.0055¥15,515.60
2005-4-1团体代庖卡0¥0.00¥0.000¥0.000¥0.00

第二种办法[封装成存储历程,大批利用一时表(效力?),便于浏览了解与更新,但合用局限无限制]:
declare@monthdatetime
set@month=2004-9-1
SELECTCustomerID,OpCount,fare,oddfare,dt,RTRIM(CAST(YEAR(dt)ASchar))
+-+RTRIM(CAST(MONTH(dt)ASchar))+-+RTRIM(DAY(dt))ASrq,
RTRIM(CAST(YEAR(dt)ASchar))+-+RTRIM(CAST(MONTH(dt)ASchar))
+-+RTRIM(DAY(0))AS[month],种别into#mingxi
FROM(SELECTCustomerID,OpCount,opfarefare,oddfare,OpDtdt,消耗AS种别
FROMT_ConsumeRec
UNIONALL
SELECTCustomerID,OpCount,infare-outfarefare,oddfare,cashDtdt,
出纳AS种别
FROMT_Cashrec)l
SELECTT_Customers.CustomerID,t_dpcode.DpCode1into#custid_dpcode1
FROM(SELECTDpCode1,DpCode1+DpCode2+DpCode3ASdpcode
FROMT_Department)t_dpcodeINNERJOIN
T_CustomersONt_dpcode.dpcode=T_Customers.Account

SELECTcustid_dpcode1.DpCode1,COUNT(*)AS开户人次,SUM(l.in_out_fare)
AS开户后第一次存款额into#kh
FROM(SELECTT_Customers.CustomerID,RTRIM(CAST(YEAR(T_Customers.OpenDt)
ASchar))+-+RTRIM(CAST(MONTH(T_Customers.OpenDt)ASchar))
+-+RTRIM(DAY(0))AS[month],ISNULL([first].in_out_fare,0)
ASin_out_fare
FROMT_CustomersLEFTOUTERJOIN
(SELECTmin_opcount.CustomerID,
T_CashRec.InFare-T_CashRec.OutFareASin_out_fare
FROM(SELECTCustomerID,MIN(OpCount)ASmin_opcount
FROMT_CashRec
GROUPBYCustomerID)min_opcountINNERJOIN
T_CashRecON
min_opcount.CustomerID=T_CashRec.CustomerIDAND
min_opcount.min_opcount=T_CashRec.OpCount)[first]ON
T_Customers.CustomerID=[first].CustomerID)lINNERJOIN
#custid_dpcode1custid_dpcode1ONl.CustomerID=custid_dpcode1.CustomerID
WHERE(l.[month]=@month)
GROUPBYcustid_dpcode1.DpCode1

SELECTcustid_dpcode1.DpCode1,SUM(mingxi.fare)AS存存款额,COUNT(*)
AS存存款次数into#cq
FROM#mingximingxiINNERJOIN
#custid_dpcode1custid_dpcode1ONmingxi.CustomerID=custid_dpcode1.CustomerID
WHERE(mingxi.种别=出纳)AND(mingxi.[month]=@month)
GROUPBYcustid_dpcode1.DpCode1

SELECTcustid_dpcode1.DpCode1,SUM(mingxi.fare)AS消耗额,COUNT(*)
AS消耗次数into#xf
FROM#mingximingxiINNERJOIN
#custid_dpcode1custid_dpcode1ONmingxi.CustomerID=custid_dpcode1.CustomerID
WHERE(mingxi.种别=消耗)AND(mingxi.[month]=@month)
GROUPBYcustid_dpcode1.DpCode1

SELECTcustid_dpcode1.DpCode1,SUM(custid_oddfare.oddfare)AS卡余额总额into#kye
FROM(SELECTcustid_max_opcount.CustomerID,mingxi_.oddfare
FROM(SELECTCustomerID,MAX(OpCount)ASmax_opcount
FROM#mingximingxi
WHERE([month]<=@month)
GROUPBYCustomerID)custid_max_opcountINNERJOIN
#mingximingxi_ONcustid_max_opcount.CustomerID=mingxi_.CustomerIDAND
custid_max_opcount.max_opcount=mingxi_.OpCount)
custid_oddfareINNERJOIN
#custid_dpcode1custid_dpcode1ONcustid_oddfare.CustomerID=custid_dpcode1.CustomerID
GROUPBYcustid_dpcode1.DpCode1

select@month月份,dpt.dpname1部门,isnull(开户人次,0)开户人次,isnull(开户后第一次存款额,0)开户后第一次存款额,isnull(消耗额,0)消耗额,isnull(消耗次数,0)消耗次数,isnull(存存款额,0)存存款额,isnull(存存款次数,0)存存款次数,isnull(卡余额总额,0)卡余额总额
from(SELECTDISTINCTDpCode1,DpName1
FROMT_Department)dptleftjoin#khkhonkh.dpcode1=dpt.dpcode1leftjoin#cqcqon
cq.dpcode1=dpt.dpcode1leftjoin#xfxfonxf.dpcode1=dpt.dpcode1leftjoin#kyekye
onkye.dpcode1=dpt.dpcode1

droptable#mingxi
droptable#custid_dpcode1
droptable#kh
droptable#cq
droptable#xf
droptable#kye

越来越多的开发者将继续选择MySQL。Evans的总裁JohnAndrews表示,MySQL学习教程用户对MySQL和其他开源数据库的评价正在赶上甚至超过很多专有商业数据库软件。
小女巫 该用户已被删除
沙发
发表于 2015-1-19 15:40:35 | 只看该作者
原来的计算字段其实和虚拟字段很像。只是管理方面好了而已,性能方面提高不多。但是SQL2005提供了计算字段的持久化,这就提高了查询的性能,但是会加重insert和update的负担。OLTP慎用。OLAP可以大规模使用。
板凳
发表于 2015-1-28 07:11:28 | 只看该作者
大家注意一点。如下面的例子:
兰色精灵 该用户已被删除
地板
发表于 2015-2-13 02:14:18 | 只看该作者
我个人认为就是孜孜不懈的学习
金色的骷髅 该用户已被删除
5#
发表于 2015-3-3 13:10:11 | 只看该作者
我们学到了什么?思考问题的时候从表的角度来思考问
柔情似水 该用户已被删除
6#
发表于 2015-3-11 11:16:43 | 只看该作者
再开发调试阶段和OLAP环境中,外键是可以建立的。新版本中加入了SETNULL和SETDEFAULT属性,能够提供能好的级联设置。
乐观 该用户已被删除
7#
发表于 2015-3-18 08:05:48 | 只看该作者
学习SQL语言的话如果要学会去做网站就不是很难!但是要做数据库管理的话就有难度了!
admin 该用户已被删除
8#
发表于 2015-3-25 14:58:09 | 只看该作者
光写几个SQL实在叫无知。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-5-3 14:43

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表