30/09/2018, 20:45

SQL SERVER .Xin ý tưởng Viết hàm với điều kiện như sau ( đk vét cạn )?

mình có 1 câu hỏi như sau

Lược đồ QH

phần viết hàm tính sl bán được, mã vt và tháng nhập vào thì mình làm được rồi, nhưng cái đk phía sau là nếu tháng k nhập thì tính tất cả thì mình chưa biết cách làm,

xin cảm ơn

Nguyen Ca viết 22:59 ngày 30/09/2018

nếu tháng k nhập thì tính tất cả thì mình chưa biết cách làm,

dùng having isnull(field, gía trị thay thế)

abcxyz viết 22:53 ngày 30/09/2018

having isnull(field, gía trị thay thế) giá trị thay thế ở đây có thể để nhiều giá trị được k anh

vì tính tất cả các tháng thì nhiều nhất là 12 tháng= 12 giá trị
e thử thì nó chỉ chấp nhận 2 tham số là fiel , và giá trị thay thế

thêm cái điều kiện trên thì having isnull phải làm ntn để nhận được 12 giá trị nhỉ

USE KHACHHANG
GO 
CREATE FUNCTION f_tongslbanduoc
(
@mavt nvarchar(5),
@thang tinyint
)
RETURNS int
BEGIN
	DECLARE @sl int
	SELECT @sl = SUM (VT.SL)
	FROM HOADON,
	(
		SELECT CHITIETHOADON.MAHD, MAVT ,SL
		FROM CHITIETHOADON
		WHERE (CHITIETHOADON.MAVT = @mavt)
	)AS VT
	WHERE (HOADON.MAHD = VT.MAHD) AND (MONTH(HOADON.NGAY) = @thang)
	RETURN @sl
END
Nguyen Ca viết 22:50 ngày 30/09/2018

tương sql không.
nếu hàm thì đơn gian hơn.
thêm 2 biến cục bộ(startdate, enđate), kiêm tra nếu tháng nhập vào là null. thì sét giá trị biện đó là khoảng thời gian cần lấy, trường hợp khác null thì set cùng ngày.
sau đó điêu kiện sẽ như thế này

MONTH(HOADON.NGAY) >= startdate and MONTH(HOADON.NGAY) <= enddate
abcxyz viết 22:57 ngày 30/09/2018

MONTH(HOADON.NGAY) >= startdate and MONTH(HOADON.NGAY) <= enddate

CHỖ NÀY E THAY BẰNG
( MONTH(HOADON.NGAY) BETWEEN @startdate AND @endate)

có ổn k nhỉ,

USE KHACHHANG
GO 
CREATE FUNCTION f_tongslbanduoc6
(
@mavt nvarchar(5),
@thang tinyint
)
RETURNS int
BEGIN
	DECLARE @sl int, @startdate tinyint, @endate tinyint
	IF (@thang IS NULL) 
		BEGIN 
			SET @startdate = 1
			SET @endate = 12
		END
	ELSE 
		BEGIN
			SET @startdate = @thang
			SET @endate = @thang
		END
	SELECT @sl = SUM (VT.SL)
		FROM HOADON,
		(
			SELECT CHITIETHOADON.MAHD, MAVT ,SL
			FROM CHITIETHOADON
			WHERE (CHITIETHOADON.MAVT = @mavt)
		)AS VT
		WHERE (HOADON.MAHD = VT.MAHD) AND ( MONTH(HOADON.NGAY) >= @startdate AND  MONTH(HOADON.NGAY) <=@endate)
	RETURN @sl
END

khi e gọi hàm

USE KHACHHANG
GO
SELECT dbo.f_tongslbanduoc6 ('VT01')

k nhập vào tháng thì lỗi

Msg 313, Level 16, State 2, Line 1
An insufficient number of arguments were supplied for the procedure or function dbo.f_tongslbanduoc6.

là sao ta?

Nguyen Ca viết 22:45 ngày 30/09/2018

đươc, nó là điều kiện trong đoạn. em truyên thiếu tham sô tháng thì bi sai la đúng rồi, không thì dùng optional parameter.
ref: https://technet.microsoft.com/en-us/library/ms189330(v=sql.105).aspx

abcxyz viết 22:45 ngày 30/09/2018

nhưng đề bài là , nếu k nhập tham số tháng , thì tính tất cả các tháng, nghĩa là ng dùng chỉ nhập mỗi mã vật tư mà anh? thế phải làm sao ạ

SELECT dbo.f_tongslbanduoc6 (‘VT01’)

Nguyen Ca viết 22:58 ngày 30/09/2018

đọc kỹ cái link anh đưa. không hỏi khi chưa đọc xong.

abcxyz viết 23:01 ngày 30/09/2018

e chưa đọc , giờ e mới đọc tks a

abcxyz viết 23:01 ngày 30/09/2018
USE AdventureWorks2008R2;
GO
IF OBJECT_ID('Sales.uspGetSalesYTD', 'P') IS NOT NULL
    DROP PROCEDURE Sales.uspGetSalesYTD;
GO
CREATE PROCEDURE Sales.uspGetSalesYTD
@SalesPerson nvarchar(50) = NULL  -- NULL default value
AS 
    SET NOCOUNT ON; 

-- Validate the @SalesPerson parameter.
IF @SalesPerson IS NULL
BEGIN
   PRINT 'ERROR: You must specify the last name of the sales person.'
   RETURN
END
-- Get the sales for the specified sales person and 
-- assign it to the output parameter.
SELECT SalesYTD
FROM Sales.SalesPerson AS sp
JOIN HumanResources.vEmployee AS e ON e.BusinessEntityID = sp.BusinessEntityID
WHERE LastName = @SalesPerson;
RETURN
GO

e chưa hiểu đoạn này lắm, cái tham số mặc định ấy ạ

Nguyen Ca viết 22:56 ngày 30/09/2018

nó đang check NULL thôi, muốn tự handle lỗi, trả về message mong muốn. tham số đó có ý nghĩa nếu không truyền thì sẽ la có giá trị NULL

abcxyz viết 22:50 ngày 30/09/2018

e vẫn chưa rõ về tham số mặc định của hàm trong sql , a có thể cho e 1 ví dụ k ạ
ví dụ đơn giản thôi

Nguyen Ca viết 23:01 ngày 30/09/2018
GO
CREATE PROCEDURE dbo.my_proc
    @first int = NULL,  -- NULL default value
    @second int = 2,    -- Default value of 2
    @third int = 3      -- Default value of 3
AS 
    SET NOCOUNT ON;
    SELECT @first, @second, @third;
GO

như em thấy ở trên

    @first int = NULL,  -- NULL default value
    @second int = 2,    -- Default value of 2
    @third int = 3      -- Default value of 3

cái này, khi em không goi hàm thì sẽ có giá trị là NULL, 2,3

EXECUTE dbo.my_proc; -- No parameters supplied
GO
result:
NULL  2  3

khi có truyền param:

EXECUTE dbo.my_proc 10, 20, 30;-- All parameters supplied
GO
result:
10  20  30

không biết áp dụng nữa. thì cách làm là “thử và sai”. code chạy thử là biết

abcxyz viết 22:59 ngày 30/09/2018

SET NOCOUNT ON;
nó báo k dùng trong hàm ạ
thế e mới k chạy được

abcxyz viết 22:47 ngày 30/09/2018
USE KHACHHANG
GO 
CREATE FUNCTION f_tongslbanduoc6
(
@mavt nvarchar(5),
@thang tinyint = NULL
)
RETURNS int
BEGIN

	DECLARE @sl int, @startdate tinyint, @endate tinyint
	IF (@thang IS NULL) 
		BEGIN 
			SET @startdate = 1
			SET @endate = 12
		END
	ELSE 
		BEGIN
			SET @startdate = @thang
			SET @endate = @thang
		END
	SELECT @sl = SUM (VT.SL)
		FROM HOADON,
		(
			SELECT CHITIETHOADON.MAHD, MAVT ,SL
			FROM CHITIETHOADON
			WHERE (CHITIETHOADON.MAVT = @mavt)
		)AS VT
		WHERE (HOADON.MAHD = VT.MAHD) AND ( MONTH(HOADON.NGAY) >= @startdate AND  MONTH(HOADON.NGAY) <=@endate)
	RETURN @sl
END

NẾU DÙNG SET NOCOUNT ON; ( cái này e tìm hiểu thì là bỏ qua thông báo lỗi)
thì lỗi

Msg 443, Level 16, State 15, Procedure f_tongslbanduoc6, Line 8
Invalid use of a side-effecting operator ‘SET OPTION ON’ within a function.

còn nếu k bỏ SET NOCOUNT ON;

thì khi gọi hàm

SELECT dbo.f_tongslbanduoc6 (‘VT05’) vẫn bị lỗi

Nguyen Ca viết 23:01 ngày 30/09/2018

SELECT dbo.f_tongslbanduoc6 (‘VT05’) vẫn bị lỗi

SELECT dbo.f_tongslbanduoc6 ('VT05',NULL) ;
SELECT dbo.f_tongslbanduoc6 ('VT05',default); 

cái của em là function không phải procedure.

abcxyz viết 23:01 ngày 30/09/2018

thì câu hỏi của e từ đầu là viết hàm mà

abcxyz viết 22:49 ngày 30/09/2018

nhưng đề yêu cầu
nếu tham số thứ 2 k nhập

nghĩa là chỉ có như thế này
SELECT dbo.f_tongslbanduoc6 (‘VT01’)
chứ hay là phải nhập null, hoặc default vào tham số thứ 2 ạ?

abcxyz viết 22:58 ngày 30/09/2018

anh ơi, a cho e hỏi chút
a có tài liệu môn thiết kế cơ sở dữ liệu k, cho e xin với tks a

Nguyen Ca viết 22:52 ngày 30/09/2018

không em ơi, không con giữ cuốn nào

abcxyz viết 22:46 ngày 30/09/2018

vâng,tks a

Bài liên quan
0