Proc

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 64

STORE

PROCEDURE
(THỦ TỤC)
Võ Văn Bình
NỘI DUNG

Thủ tục với Thủ tục với


Khái niệm Thủ tục tham số đầu tham số đầu
vào ra

Thủ tục có Sử dụng Tham số


Giao tác
lệnh trả về bảng tạm cursor bên
(Tracsaction)
Return trong thủ tục trong thủ tục
Stored procedure là một tập
các lệnh Transact SQL được đặt
tên và lưu trữ trong database
server.

Có thể nhận tham số vào và


KHÁI tham số trả giá trị ra.
NIỆM

Trả về trạng thái thực thi của


procedure là thành công hay
không thành công.
KHÁI NIỆM

 Thủ tục nội tại là một tập hợp chứa các dòng lệnh, các biến và các cấu trúc điều
khiển trong ngôn ngữ Transaction-SQL dùng để thực hiện một hành động nào đó.
Các nét đặc trưng
• Tên thủ tục.
• Tham số truyền giá trị vào.
• Tham số nhận giá trị ra .
KHÁI • Trong thủ tục nội tại được phép gọi
NIỆM thực thi một thủ tục nội tại khác.
• Có tính cục bộ bên trong một cơ sở
dữ liệu lưu trữ thủ tục đó.
• Có thể gọi thực hiện trong môi trường
không phải Microsoft SQL Server.
KHÁI NIỆM

Lợi ích của thủ tục:


o Tốc độ xử lý của các thủ tục nội tại rất nhanh.
o Việc tổ chức và phân chia các xử lý thành hai nơi khác
nhau: tại máy chủ hoặc tại máy trạm sẽ giúp giảm thời
gian xây dựng ứng dụng.
Thủ tục hệ thống
o Bắt đầu bằng chữ sp_ và hầu hết tất cả các thủ tục hệ
thống được lưu trữ bên trong CSDL Master.
 Khái niệm
 Thủ tục
 Thủ tục với tham số đầu vào
 Thủ tục với tham số đầu ra
NỘI DUNG  Thủ tục có lệnh trả về Return
 Sử dụng bảng tạm trong thủ tục
 Tham số cursor bên trong thủ tục
 Giao tác (Tracsaction)
THỦ TỤC

Tạo mới thủ tục


Cú pháp:
CREATE PROC[EDURE] Tên_thủ_tục
AS
[Declare biến_cục_bộ]
các_lệnh
THỦ TỤC

Ví dụ: Tạo procedure để liệt kê danh sách tất cả


các mặt hàng.
CREATE PROC P_MH
AS
SELECT * FROM MH
 Gọi thực thi thủ tục
EXEC[UTE] P_MH
THỦ TỤC

Ví dụ: Tạo procedure để cập nhật giá cho mặt hàng
kẹo là 17000.
create proc P_capnhat
as
update ctdh set Dgdat = 17000
where mamh = 'keo'
Gọi thực thi thủ tục
exec P_capnhat
THỦ TỤC

Ví dụ: Cho biết số lượng sinh viên trong lớp?


CREATE PROC P_DEMSV @MALOP
CHAR(9), @SLSV SMALLINT OUTPUT
AS
SELECT @SLSV = COUNT(*) FROM SV
WHERE @MALOP = MALOP
THỦ TỤC

DECLARE @SL SMALLINT


EXEC P_DemSV '07CDTH',
@SLSV = @SL OUTPUT
PRINT 'SO LUONG SINH VIEN O LOP: ' +
CAST(@SL AS CHAR(3))
THỦ TỤC

Thay đổi nội dung thủ tục


Cú pháp:
ALTER PROC[EDURE] Tên_thủ_tục
AS [Declare biến_cục_bộ]
Các_lệnh.
THỦ TỤC

Alter Proc P_Demsv @Malop Char(9)


As
Select Malop, Tenlop From Lop
Where @Malop = Malop
THỦ TỤC

Ví dụ: cho lược đồ CSDL như sau:


MAT_HG(MaMH, TenMH, DVT, MaNCC)
PH_XUAT(SoPX, NgayXuat, SoDH)
CTPX(MaMH, SoPX, SLXuat, DGX)
DDH(MaDH, NgDat)
CTDH(MaDH, MaMH, SLD, DGDat)
THỦ TỤC

Ví dụ: Cho biết mặt hàng nào có SO LUONG


bán cao nhất trong tháng 01/2007.
THỦ TỤC
CREATE PROC p_MaxSLBan
AS Declare @TenMH varchar(50), @MaxSL int
Select @TenMH = RTRIM(TenMH), @MaxSL = SLXuat
From CTPX, PH_XUAT, MAT_HG
Where CTPX.SoPX = PH_XUAT.SoPX
And MAT_HG.MaMH = CTPX.MaMH
And convert(char(7), NgayXuat, 21) = ‘2007-01’
And SLXuat = (Select Max(SLXuat) From CTPX, PH_XUAT
Where CTPX.SoPX = PH_XUAT.SoPX
And convert(char(7), NgayXuat, 21) = ‘2007-01’)
Print @TenMH + ‘Co doanh so cao nhat la’ +
Cast(@MaxSL as char(10))
THỦ TỤC

Gọi thực hiện thủ tục


exec p_maxslban
THỦ TỤC

Ví dụ: Cho biết mặt hàng nào có SO LUONG bán


cao nhất trong tháng 02/2015. Nếu không có thì
hãy thông báo.
THỦ TỤC

alter proc p_maxslban


AS
declare @tenmh nvarchar(50), @maxsl int
if not exists(select mamh from CTPX, PH_XUAT
where CTPX.SoPX = PH_XUAT.SoPX
and convert(char(7), NgayXuat, 21)= '2015-03')
Begin
Print N'tháng 03 nam 2015 chưa bán mặt hàng nào cả';
Return
End
THỦ TỤC

Select @tenmh = rtrim(tenmh), @maxsl = slxuat From CTPX,


PH_XUAT, MAT_HG
Where CTPX.SoPX = PH_XUAT.SoPX and
MAT_HG.mamh = CTPX.mamh and
convert(char(7),ngayxuat, 21)= '2015-03' and
slxuat = (select max(slxuat) from CTPX, PH_XUAT
where CTPX.SoPX= PH_XUAT.SoPX and
convert(char(7), ngayxuat, 21)= '2015-03')
print @tenmh + N' có doanh số cao nhất là ' + cast(@maxsl as
char(10))
THỦ TỤC

Gọi thực hiện thủ tục


exec p_maxslban
NỘI DUNG

 Khái niệm
 Thủ tục
 Thủ tục với tham số đầu vào
 Thủ tục với tham số đầu ra
 Thủ tục có lệnh trả về Return
 Sử dụng bảng tạm trong thủ tục
 Tham số cursor bên trong thủ tục
 Giao tác (Tracsaction)
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

Cú pháp:
CREATE PROC[EDURE] Tên_thủ_tục
@Tên_tham_số kiểu_dữ_liệu [= giá_trị]
AS
[Declare biến_cục_bộ]
các_lệnh
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

Ví dụ 1: Nhập vào tên sinh viên, cho biết sinh viên
đó xuất hiện bao nhiêu lần?
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

create proc p_svien @tsv varchar(50)


As
if not exists (select rtrim(Tensv) from sv where @tsv = tensv)
print ‘Khong co’
else
begin
declare @sl int
select @sl = count(*) from sv where @tsv = tensv
print 'So lan xh: ' + cast(@sl as char(2))
end
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

Gọi thực hiện thủ tục


exec p_svien ‘Nguyen Van A’
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

Ví dụ 2: Tạo thủ tục tính tổng giá trị của một phiếu
xuất hàng hoá có một tham số vào là số phiếu xuất
với kiểu dữ liệu là chuỗi.
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

CREATE PROC p_TGTX @SoPX char(5)


AS Declare @TongTG money
Select @TongTG=SUM(SLX*DGX)
From CTPX
Where @SoPX=SoPX
Print ‘Tri gia phieu xuat’+ cast(@sopx as char(5))
Print ‘là: ’ + CAST(@TongTG as char(10))
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

Gọi thực hiện thủ tục


Exec p_TGTX ‘PX003’
Hoặc:
Exec p_TGTX @SoPX=‘PX003’
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

Ví dụ 3: Tạo thủ tục tính số lượng đặt hàng


của một mặt hàng trong một đơn đặt hàng có
2 tham số đầu vào là số đặt hàng và mã mặt
hàng.
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

create proc p_tinhsldat @sodh char(4), @mamh char(4)


AS Declare @Sldat int
if not exists (select madh from ctdh
where madh = @sodh and mamh = @mamh)
begin
print ‘khong hop le, xem lai don dat hang’
return
end
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

Select @SLDat = SLDat


From CTDH
Where @sodh= madh and @mamh = mamh
Print ‘Don dat hang ’ + @SoDH
Print ‘Voi ma mat hang ’ + @MaMH
Print ‘Co so luong dat la: ’ + Cast(@SLDat as varchar(10))
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

Gọi thực hiện thủ tục:


Exec p_TinhSLDat ‘001’, ‘Gao’
Hoặc
exec p_tinhsldat @mamh=‘gao’, @sodh = ‘001’
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

Ví dụ 4: tạo thủ tục thêm mới dữ liệu vào bảng


MAT_HANG với tên p_MATHANG_Them gồm
có 4 tham số vào chính là các giá trị them mới cho
các cột trong bảng MAT_HANG: mã mặt hàng, tên
mặt hàng, đơn vị tính, mã NCC. Trong đó cần kiểm
tra các ràng buộc dữ liệu phải hợp lệ trước khi thực
hiện lệnh INSERT INTO để thêm dữ liệu vào bảng
MAT_HANG. Mã mặt hàng phải duy nhất.
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

Create proc p_mathang_them


@mamh char(4), @tenmh varchar(50), @dvt char(10),@ncc char(10)
As
if exists(select mamh from mh where mamh = @mamh)
Begin
print N'Mã mặt hàng ['+@MaMH+'] đã có'
return
end
insert into mh(mamh, tenmh, dvt, mancc)
values(@mamh, @tenmh, @dvt, @ncc)
THỦ TỤC VỚI THAM SỐ ĐẦU VÀO

Gọi thực hiện thủ tục


exec p_mathang_them 'Dau', 'Dau nuoc cot dua',
'goi', ' Cty Z'
NỘI DUNG

 Khái niệm
 Thủ tục
 Thủ tục với tham số đầu vào
 Thủ tục với tham số đầu ra
 Thủ tục có lệnh trả về Return
 Sử dụng bảng tạm trong thủ tục
 Tham số cursor bên trong thủ tục
 Giao tác (Tracsaction)
THỦ TỤC VỚI THAM SỐ ĐẦU RA

Cú pháp:
CREATE PROC Tên_thủ_tục
@Tên_tham_số kiểu_dữ_liệu OUTPUT [,…]
AS
[Declare Biến cục bộ]
Các_lệnh
THỦ TỤC VỚI THAM SỐ ĐẦU RA

Ví dụ 1: Đếm số lượng sinh viên trong lớp.


create proc p_demsv @malop char(9),@slsv
smallint output
as
select @slsv=count(*) from sv
where @malop=malop
THỦ TỤC VỚI THAM SỐ ĐẦU RA

Gọi thực hiện.


declare @sl smallint
exec p_demsv '08cdth', @slsv =@sl output
print 'so luong sinh vien o lop: ' + cast(@sl as char(3))
THỦ TỤC VỚI THAM SỐ ĐẦU RA

Ví dụ 2: tạo thủ tục tính số lượng đặt hàng của


một mặt hàng trong một đơn đặt hàng có 2 tham số
vào là số đặt hàng và mã mặt hàng, trả ra số lượng
đặt hàng của vật tư tương ứng trong đơn đặt hàng
thông qua tham số đầu ra.
THỦ TỤC VỚI THAM SỐ ĐẦU RA
create proc p_tinhsldat
@sodh char(4), @mamh char(4), @sldat int output
As
if not exists(select madh from ctdh
Where madh=@sodh And mamh=@mamh)
Begin
Print 'khong co don hang nay, xem lai don dat hang‘
Return
End
Select @SLDat = SL From CTDH
Where Madh = @sodh and mamh = @mamh
THỦ TỤC VỚI THAM SỐ ĐẦU RA
Gọi thực hiện thủ tục
DECLARE @SLDatHang int
EXEC p_TinhSLDat @MaMH = ‘Gao’,
@SoDH = ‘001’, @SLDat = @SLDatHang OUTPUT
Print ‘Don dat hang 001 với mặt hàng Gao’
Print ‘co so luong dat la: ’ + CAST(@SLDatHang AS
varchar(10))
NỘI DUNG

 Khái niệm
 Thủ tục
 Thủ tục với tham số đầu vào
 Thủ tục với tham số đầu ra
 Thủ tục có lệnh trả về Return
 Sử dụng bảng tạm trong thủ tục
 Tham số cursor bên trong thủ tục
 Giao tác (Tracsaction)
THỦ TỤC CÓ LỆNH TRẢ VỀ RETURN
Return không có giá trị chỉ định thì thủ tục sẽ trả
về giá trị là không (0).
Return [Số_nguyên]
THỦ TỤC CÓ LỆNH TRẢ VỀ RETURN
Ví dụ: Tạo thủ tục tính tổng số lượng đặt hàng của
một mặt hàng đối với một nhà cung cấp chỉ định,
kiểm tra xem giá trị của mặt hàng và mã nhà cung
cấp mà người dùng truyền vào thủ tục có đúng hay
không? Qui định thủ tục trả về 1 khi mã mặt hàng
không tồn tại, trả về 2 khi mã nhà cung cấp không
tồn tại.
THỦ TỤC CÓ LỆNH TRẢ VỀ RETURN
create proc p_tgsldat @mancc char(10), @mamh char(10), @tgsldat
int output
As
if not exists(select * from mh where mamh = @mamh) return 1
if not exists(select * from mh where mancc = @mancc) return 2
select @tgsldat = sum(ctdh.sld)
from ctdh, ddh, mh
where ddh.madh = ctdh.madh and mancc = @mancc and mh.mamh =
@mamh
if @tgsldat is null set @tgsldat=0
return
THỦ TỤC CÓ LỆNH TRẢ VỀ RETURN
 Gọi thực hiện thủ tục:
declare @tgsld int, @ketqua int
exec @ketqua = p_tgsldat 'Cty a', 'gao', @tgsldat = @tgsld output
if @ketqua =1
Print N'Mã mặt hàng không hợp lệ‘
else if @ketqua=2
Print N'Mã nhà cung cấp không hợp lệ‘
else
Print N'Tổng số lượng đặt là: ' +
cast(@tgsld as char(10))
NỘI DUNG

 Khái niệm
 Thủ tục
 Thủ tục với tham số đầu vào
 Thủ tục với tham số đầu ra
 Thủ tục có lệnh trả về Return
 Sử dụng bảng tạm trong thủ tục
 Tham số cursor bên trong thủ tục
 Giao tác (Tracsaction)
SỬ DỤNG BẢNG TẠM TRONG SP
Cú pháp:
SELECT danh_sách_các_cột INTO #Tên_bảng_tạm
FROM Tên_bảng_dữ_liệu
 Chú thích:
• (#): tạo ra các bảng tạm cục bộ
• (##): tạo ra các bảng tạm toàn cục
SỬ DỤNG BẢNG TẠM TRONG SP
Ví dụ: Tạo thủ tục cho biết tên mặt hàng nào có doanh thu
bán ra cao nhất trong một năm tháng bất kỳ.
SỬ DỤNG BẢNG TẠM TRONG SP
create proc p_max @namthang char(7), @tenmh varchar(50) output,
@tongtien money output
as
select mh.mamh, tenmh, sum(slx*dgx) as tt into #doanhthu
from px, ctpx, mh
where px.sopx = ctpx.sopx and ctpx.mamh = mh.mamh and
convert(char(7), ngxuat, 21) = @namthang
group by mh.mamh, tenmh
order by 3 desc
select top 1 @tenmh=tenmh, @tongtien = tt from #doanhthu
SỬ DỤNG BẢNG TẠM TRONG SP
Gọi thực hiện thủ tục
Declare @tenmh varchar(50), @tongtien money
Exec p_max '2009-10', @tenmh output, @tongtien output
if @tenmh is null
Print N'không có dữ liệu tính toán'
else
print @tenmh + N' có doanh thu cao nhất' + N'
là'+cast(@tongtien as char(10))+ ' vnd'
NỘI DUNG

 Khái niệm
 Thủ tục
 Thủ tục với tham số đầu vào
 Thủ tục với tham số đầu ra
 Thủ tục có lệnh trả về Return
 Sử dụng bảng tạm trong thủ tục
 Tham số cursor bên trong thủ tục
 Giao tác (Tracsaction)
THAM SỐ CURSOR BÊN TRONG SP
Tham số cursor trả về danh sách các dòng dữ liệu
theo điều kiện chọn lọc nào đó.
Cursor được chia làm 2 phần: bên trong thủ tục và
bên ngoài thủ tục.
o Các hành động trong thủ tục: định nghĩa dữ liệu cho
biến kiểu cursor và mở cursor.
o Các hành động bên ngoài thủ tục: đọc từng dòng dữ liệu
bên trong cursor và sau cùng là đóng cursor lại
THAM SỐ CURSOR BÊN TRONG SP
Ví dụ: tạo thủ tục trả về danh sách các mã mặt
hàng đã bán ra nhiều nhất trong năm tháng nào đó.
Bước 1: tạo thủ tục có tham số kiểu dữ liệu cursor
chứa danh sách các mặt hàng đã bán ra nhiều
nhất.
THAM SỐ CURSOR BÊN TRONG SP
create proc p_tinhdsoban
@namthang char(6),
@cur_dsmh cursor varying output
as
THAM SỐ CURSOR BÊN TRONG SP
Ví dụ: cho lược đồ CSDL như sau:
MAT_HG(MaMH, TenMH, DVT, MaNCC)
PH_XUAT(SoPX, NgXuat, SoDH)
CTPX(MaMH, SoPX, SLX, DGX)
DDH(MaDH, NgDat)
CTDH(MaDH, MaMH, SLD, DGDat)
THAM SỐ CURSOR BÊN TRONG SP
Tạo bảng tạm tính ra tổng số lượng bán
select ctpx.mamh, sum(slx) as tongslban into #tongslban
from ctpx, mh, px
where convert(char(6), ngxuat, 112) = @namthang
and ctpx.mamh=mh.mamh
and ctpx.sopx=px.sopx
group by ctpx.mamh
THAM SỐ CURSOR BÊN TRONG SP
Kiểm tra dữ liệu có phát sinh
if exists(select mamh from #tongslban)
begin
-- Khởi tạo giá trị biến CURSOR
set @cur_dsmh = cursor forward_only
for select mamh, tongslban from #tongslban
where tongslban=(select max(tongslban)
from #tongslban)
THAM SỐ CURSOR BÊN TRONG SP
Mở cursor
OPEN @cur_Dsmh
DROP TABLE #TongSLBan
Return
End
Khi không có dữ liệu phát sinh
DROP Table #TongSLBan
Return 1
THAM SỐ CURSOR BÊN TRONG SP
Bước 2: đọc cursor, nhận danh sách các mã mặt hàng
đã bán ra nhiều nhất trong tháng 01 năm 2009
Declare @cur_dsmh cursor, @gtmh int, @mamh char(4),
@tongslban int
exec @gtmh = p_tinhdsoban ‘200709’, @cur_dsmh
output
--Xử lý tiếp sau đó
IF @Gtmh = 0
THAM SỐ CURSOR BÊN TRONG SP
Begin
Print ‘danh sách các mặt hàng’
While(0=0)
Begin
Fetch Next From @cur_Dsmh INTO @MaMH, @TongslBan
IF @@Fetch_status <>0; Break;
Print ‘Mã vật tư: ’ + @MaMH
Print ‘Tổng số lượng:’ + CAST(@TongslBan AS varchar(10))
End
End
ELSE
Print ‘không có bán hàng trong năm tháng chỉ định’

You might also like