题目所述功能要求,可以用一句SQL语句实现,当然如果要传递一些参数地滤的话还是需要存储过程.
语句思路:
1.按dwbh,时间汇总个人表中金额
2.按dwbh,时间汇总单位表中金额
3.将以上两个汇总结果进行关联,关联的条件是相同dwbh、相同时间情况下金额不同的记录.即可以实现金额不相同的数据筛选出来.
"--"符号为注解,以下语句中的中文字段为假想字段,可以替换为实际字段.关键在于理解语句思路.语句如下:
select
GR.dwbh
,
GR.个人表交费时间
as
时间,GR.个人交费总金额,DW.单位交费总金额,(GR.个人交费总金额
-
DW.单位交费总金额)
as
差额
from
(
select
dwbh,个人表交费时间,sum(交费金额)
as
个人交费总金额
--子查询汇总出个人交费表中的单位、时间、金额,并取别名为GR嵌入From子句中
from
bcd
group
by
dwbh,交费时间
)
as
GR
inner
join
--
将上下两个子查询进行内联
(
select
dwbh,单位表交费时间,sum(交费金额)
as
单位交费总金额
--子查询汇总出单位交费表中的单位、时间、金额,并取别名为DW嵌入From子句中
from
abc
groub
by
dwbh,交费时间
)
as
DW
on
GR.dwbh
=
DW.dwbh
and
GR.个人表交费时间
=
DW.单位表交费时间
and
GR.个人交费总金额
<>
DW.单位交费总金额
--两个子查询内联的条件是单位编号相同,时间相同,但金额不同的记录
Ⅱ SQL存储过程怎么写这样套复杂的写法.
create proc proc1
@B1 int,@B2 int,@ID int output
as
declare @K1 int,@K2 int,@K3 varchar(20)
begin
exec proc2 @K1,@K2,@K3 output --@K3输出参数 就是你的tablename
select @ID=ID from @K3 where B1=@B1 and B2=@B2
end
你提供的不详细 我只能写个思路给你。。 调用proc1存储过程先调用proc2传出一个表名 然后根据传入的参数输出这个表名的ID字段。。
Ⅲ 如何解决执行sql存储过程(大数据量复杂
插入是sql会把数据存到inserted(我不确定对不对啊)表里面,是在内存中的,当插入到你要插入的表了之后才会删除干才插入到inserted表里的数据,是需要消耗内存的。
消耗的内存都是一样的,只是一个是预编译的(存储过程),一个是即时的。使用存储过程效率要高一些。
Ⅳ 谁能提供一下多表复杂查询的Sql语句用到语法,最好用存储过程
那就写个存储过程,然后再在存储过程里面写多表联结查询的sql语句喽~ 下面是创建存储过程的关键字:
create proc 存储过程名称
as
begin
//多表联结查询的sql语句
end
go
exec 存储过程名称
希望我的回答对你有所帮助,谢谢采纳!
Ⅳ SQL存储过程
楼上说的都不对,这明明是SqlServer的存储过程,你们却写成了Oracle的存储过程,两个语法还是有所区别的,应该这样:
create procere insert_stu
(
@xh varchar(7),
@xm varchar(10),
@xb varchar(2),
@nl tinyint,
@szx varchar(20)
)
as
begin
insert into student values (@xh,@xm,@xb,@nl,@szx);
end
以上,希望对你有所帮助!
Ⅵ sql存储过程几个简单
例1:
create proc proc_stu
@sname varchar(20),
@pwd varchar(20)
as select * from ren where sname=@sname and pwd=@pwd
go
查看结果:proc_stu 'admin','admin' 例2:
下面的存储过程实现用户验证的功能,如果不成功,返回0,成功则返回1.
CREATE PROCEDURE VALIDATE @USERNAME CHAR(20),@PASSWORD CHAR(20),@LEGAL BIT OUTPUT
AS
IF EXISTS(SELECT * FROM REN WHERE SNAME = @USERNAME AND PWD = @PASSWORD)
SELECT @LEGAL = 1 ELSE
SELECT @LEGAL = 0 在程序中调用该存储过程,并根据@LEGAL参数的值判断用户是否合法。
Ⅶ SQL 存储过程
仔细思考一下我的解决办法是否妥当:
因为过程开头部分已经定义了4个变量,并且都赋初值为'0',
那么,我们做两处变动:
1、在你的select语句执行前,我们写上4个判断,判断这4个变量是否被传入了值,未传入时怎么样处理。
2、修改select语句的where子句(语句中有三个“=”改成like)。
过多的描述也许难以看懂,我直接写出来,新增或修改的部分,我在后面用了注释“//--★”(我的写法是基于Sybase的,你可以看懂的。当然你也可以先看一下后面的【总结】):
if exists(………………………………)
drop ……………………
go
create Proc Proc_ManualSign
@BranchId varchar(10) = '0',
……………………
……………………
@UserName varchar(50) = '0'
as
begin //--★sybase写法,用于过程开始,参考你的数据库,看是否需要加
if @BranchId = '0' //--★如果@BranchId依然为初始值(未传入参数)
select @BranchId = '%' //--★那么将@BranchId赋值为'%'
if @DepartId = '0' //--★如果@DepartId依然为初始值(未传入参数)
select @DepartId = '%' //--★那么将@DepartId赋值为'%'
if @UserId = '0' //--★如果@UserId依然为初始值(未传入参数)
select @UserId = '%' //--★那么将@UserId赋值为'%'
if @UserName = '0' //--★如果@UserName依然为初始值(未传入参数)
select @UserName = '%' //--★那么将@UserName赋值为'%'
select …………
……………………
and b.BranchId like @BranchId --机构 //--★你原来的“=”改成了“like”
and d.DepartId like @DepartId --部门 //--★你原来的“=”改成了“like”
and m.UserId like @UserId --用户Id //--★你原来的“=”改成了“like”
and u.UserName like '%'+@UserName+'%' --用户名
end //--★sybase写法,用于标注过程结束,参考你的数据库,看是否需要加
go
======================================================================
【★★--总结--★★】我的办法:
4个变量初值为'0',excute执行该过程时,if语句就要依次判断各变量的当前值,判断的结果无非两种:①.未传入值(还是'0'),②.传入了值(不是'0')
①.未传入值
if语句判断出某变量未传入值,则将该变量置为'%',那么select语句的where条件中就是该字段 like '%',也就是该字段的检索条件为任意的。
②.传入了值
传入了值,则if语句的判断结果为假(False),那么直接跳出判断去执行select语句,虽然where子句的条件中用的是 like 介词,但没有通配符'%'的话,like 的作用也就是'=',即:【like '销售部'】的作用也就是 【='销售部'】,所以也满足了输入参数的精确查询要求。
执行时:
假如什么参数也不传入,即:查询全部的信息
excute Proc_ManualSign '0', '0', '0', '0'
假如仅部门和用户ID传入参数,则
excute Proc_ManualSign '0', '开发部', '319', '0'
Ⅷ sql存储过程
一、简单的储存过程:
1、创建一个存储过程
create procere GetUsers()
begin
select * from user;
end;12345
2、调用存储过程
call GetUsers();12
3、删除存储过程
drop procere if exists GetUsers;
二、带参数的存储过程
1、MySql 支持 IN (传递给存储过程) , OUT (从存储过程传出) 和 INOUT (对存储过程传入和传出) 类型的参数 , 存储过程的代码位于 BEGIN 和 END 语句内 , 它们是一系列 SQL 语句 , 用来检索值 , 然后保存到相应的变量 (通过指定INTO关键字) ;
2、下面的存储过程接受三个参数 , 分别用于获取用户表的最小 , 平均 , 最大分数 , 每个参数必须具有指定的类型 , 这里使用十进制值(decimal(8,2)) , 关键字 OUT 指出相应的参数用来从存储过程传出
create procere GetScores(
out minScore decimal(8,2),
out avgScore decimal(8,2),
out maxScore decimal(8,2)
)
begin
select min(score) into minScore from user;
select avg(score) into avgScore from user;
select max(score) into maxScore from user;
end;1234567891011
3、调用此存储过程 , 必须指定3个变量名(所有 MySql 变量都必须以 @ 开始) , 如下所示 :
call GetScores(@minScore, @avgScore, @maxScore);12
4、该调用并没有任何输出 , 只是把调用的结果赋给了调用时传入的变量 @minScore, @avgScore, @maxScore , 然后即可调用显示该变量的值 :
select @minScore, @avgScore, @maxScore;
5、使用 IN 参数 , 输入一个用户 id , 返回该用户的名字 :
create procere GetNameByID(
in userID int,
out userName varchar(200)
)
begin
select name from user
where id = userID
into userName;
end;12345678910
6、调用存储过程 :
call GetNameByID(1, @userName);
select @userName;123
参考资料
SQL存储过程使用介绍.csdn博客[引用时间2017-12-31]
Ⅸ 如何解决执行sql存储过程(大数据量复杂的sql计算操作)时,不影响用户使用
对实时性不是非常必须的功能,不要放在主业务集中操作的同时操作。这个需要引导客户。
系统的开销就在那里摆着,没有别的办法,一运行资源就占了,CPU 资源,数据库资源,内存资源。
两个办法:一个是做一个数据库复制,可以半天复制一次,也可以一天复制一次(闲时复制),根据用户对数据的敏感度决定,存储过程运行不限时间,运行时访问复制数据库,不影响主数据库。需要额外资源:数据库服务器,数据库复制时间和网络资源开销;
第二个是定制成任务,闲时执行结果放到指定表中,或者直接以文件形式导出在服务器指定位置。用的人直接读记录或者读文件就OK 了。
请参考。
Ⅹ sql复杂的存储过程写法
你的参数不知道都是什么意思
declare @xi varchar(10)
select @xi = 系 from stud where sfz = @sfz
select *
from stud a
where 系= @xi
and
(not exists(select 1 from stud where 系= a.系 and 年龄 < a.年龄)
or
not exists(select 1 from stud where 系= a.系 and 年龄 > a.年龄)
)