題目所述功能要求,可以用一句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.年齡)
)