SQL 服务器函数处理搜索表单提交和 return table 值的逻辑问题
Logic issue in SQL Server function to handle search form submission and return table value
我在 java 网络应用程序中构建了一个搜索表单,如下图所示
现在,此页面的用户需要在 6 个搜索字段中的一个或多个中输入值,或者可以进行开放式搜索,将所有字段留空。
我有以下函数获取结果。
USE [KingsBayY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[test_fn_transaction_search]
(@receiptnum varchar(4001) ='',--00040401010000021
@account varchar(4001) ='',
@FN varchar(4001) ='',
@ln varchar(4001) ='',--DateTime = '',
@dt varchar(4001) ='',
@program varchar(4001) ='',--)
@attendee varchar(4001) =''
)
--stdt
--enddt
RETURNS @resulttable TABLE
(trid int,
trdate varchar(4001), --COLLATE database_default
tramount money,
trinvoice varchar(4001),
trcashierid varchar(4001),
trvoided varchar(4001),
trrecallid varchar(4001),
trrecalltype varchar(4001),
trattendee varchar(4001),
trperiod varchar(4001),
stopbilling varchar(4001),
caccount varchar(4001),
firstname varchar(4001),
lastname varchar(4001),
trprogram varchar(4001),
itemlookupcode varchar(4001),
paydate varchar(4001)
)
AS
BEGIN
IF (@receiptnum='' and @account='' and @FN=''and @ln='' and @dt='' and @program='' and @attendee='')
INSERT INTO @resulttable
select tr.ID AS [Transaction ID], tr.Time AS [trDt], tr.Total AS [amount],
tr.ReceiptNumber AS [invoice], tr.CashierID AS [cashid],
tr.Voided AS [voided], tr.RecallID AS [recallid], tr.RecallType AS [recalltype],
tr.Comment AS [attendee], tr.ReferenceNumber AS [trperiod], tr.StopBilling AS [stopbilling],
--fields from customer
c.AccountNumber AS [accountnum], c.FirstName AS [firstname], c.LastName AS [lastname],
--fields from item
it.Description AS [programname], it.ItemLookupCode AS [trItemLookupCode],
--fields from tenderentry
tent.PaymentDate AS [paydate]
from "Transaction" tr, TransactionEntry trent, Item it, Customer c, TenderEntry tent
where trent.TransactionID = tr.ID
and tent.TransactionID = tr.ID
and trent.ItemID = it.ID
and c.ID=tr.CustomerID
and tr.RecallID =0 --parent
--and tr.RecallType=0 --parent transactions and independant sales
order by tr.id, tr.time;
else IF (@receiptnum<>'' or @account<>'' or @FN<>'' or @ln<>'' or @dt<>'' or @program<>'' or @attendee<>'')
INSERT INTO @resulttable
select tr.ID AS [Transaction ID], tr.Time AS [trDt], tr.Total AS [amount],
tr.ReceiptNumber AS [invoice], tr.CashierID AS [cashid],
tr.Voided AS [voided], tr.RecallID AS [recallid], tr.RecallType AS [recalltype],
tr.Comment AS [attendee], tr.ReferenceNumber AS [trperiod], tr.StopBilling AS [stopbilling],
--fields from customer
c.AccountNumber AS [accountnum], c.FirstName AS [firstname], c.LastName AS [lastname],
--fields from item
it.Description AS [programname], it.ItemLookupCode AS [trItemLookupCode],
--fields from tenderentry
tent.PaymentDate AS [paydate]
from "Transaction" tr, TransactionEntry trent, Item it, Customer c, TenderEntry tent
where trent.TransactionID = tr.ID
and tent.TransactionID = tr.ID
and trent.ItemID = it.ID
and c.ID=tr.CustomerID
and tr.RecallID =0 --parent transactions and independant sales
--and tr.RecallType=0 --
and(
tr.ReceiptNumber=ISNULL(@receiptnum,tr.ReceiptNumber)--invoice
or c.accountnumber=ISNULL(@account,c.accountnumber)--account
or c.FirstName=ISNULL(@FN, c.FirstName)
or c.LastName=ISNULL(@ln, c.LastName)--customer
or tr.time=ISNULL(@dt,tr.time)--date
or tr.Comment=ISNULL(@attendee,tr.Comment)
--program
)
union
select tr.ID AS [Transaction ID], tr.Time AS [trDt], tr.Total AS [amount],
tr.ReceiptNumber AS [invoice], tr.CashierID AS [cashid],
tr.Voided AS [voided], tr.RecallID AS [recallid], tr.RecallType AS [recalltype],
tr.Comment AS [attendee], tr.ReferenceNumber AS [trperiod], tr.StopBilling AS [stopbilling],
--fields from customer
c.AccountNumber AS [accountnum], c.FirstName AS [firstname], c.LastName AS [lastname],
--fields from item
it.Description AS [programname], it.ItemLookupCode AS [trItemLookupCode],
--fields from tenderentry
tent.PaymentDate AS [paydate]
from "Transaction" tr, TransactionEntry trent, Item it, Customer c, TenderEntry tent
where trent.TransactionID = tr.ID
and tent.TransactionID = tr.ID
and trent.ItemID = it.ID
and c.ID=tr.CustomerID
and tr.RecallID =0 --parent transactions and independant sales
--and tr.RecallType=0 --
and(
ISNULL(tr.ReceiptNumber,'1')= ISNULL(@receiptnum,'1')--invoice
and ISNULL(c.accountnumber,'1')= ISNULL(@account,'1')--account
and ISNULL(c.FirstName,'1')= ISNULL(@FN,'1')
and ISNULL(c.LastName,'1')= ISNULL(@ln,'1')--customer
and ISNULL(tr.time,'1')= ISNULL(@dt,'1')--date
and ISNULL(tr.Comment,'1')=ISNULL(@attendee,tr.Comment)
--program
)
order by tr.id, tr.time;
RETURN
END
我从这个过程中得到了错误的结果。我注意到的问题是,
无论如何尝试搜索.. 打开搜索,指定一个搜索参数.. 指定多个搜索参数值,程序 return 的所有结果。如何根据使用的搜索参数将其编辑为 return 仅结果?
一些搜索参数可能不完全匹配..例如参加者字段..用户可能输入 'John Doe' 而 table 有参加者列其中一个单元格值为 'John Doe - the genius'.. 我希望能够搜索在单元格值中输入的术语。我该怎么做。
这是catch-all query的一种。
ALTER FUNCTION [dbo].[test_fn_transaction_search]
(
@receiptnum VARCHAR(4001) = NULL,
@account VARCHAR(4001) = NULL,
@FN VARCHAR(4001) = NULL,
@ln VARCHAR(4001) = NULL,
@dt VARCHAR(4001) = NULL,
@program VARCHAR(4001) = NULL,
@attendee VARCHAR(4001) = NULL
)
RETURNS @resulttable TABLE
(
trid INT,
trdate VARCHAR(4001),
tramount MONEY,
trinvoice VARCHAR(4001),
trcashierid VARCHAR(4001),
trvoided VARCHAR(4001),
trrecallid VARCHAR(4001),
trrecalltype VARCHAR(4001),
trattendee VARCHAR(4001),
trperiod VARCHAR(4001),
stopbilling VARCHAR(4001),
caccount VARCHAR(4001),
firstname VARCHAR(4001),
lastname VARCHAR(4001),
trprogram VARCHAR(4001),
itemlookupcode VARCHAR(4001),
paydate VARCHAR(4001)
)
AS
BEGIN
INSERT INTO @resulttable
SELECT
tr.ID AS [Transaction ID],
tr.Time AS [trDt],
tr.Total AS [amount],
tr.ReceiptNumber AS [invoice],
tr.CashierID AS [cashid],
tr.Voided AS [voided],
tr.RecallID AS [recallid],
tr.RecallType AS [recalltype],
tr.Comment AS [attendee],
tr.ReferenceNumber AS [trperiod],
tr.StopBilling AS [stopbilling],
c.AccountNumber AS [accountnum],
c.FirstName AS [firstname],
c.LastName AS [lastname],
it.Description AS [programname],
it.ItemLookupCode AS [trItemLookupCode],
tent.PaymentDate AS [paydate]
FROM [Transaction] tr
INNER JOIN TransactionEntry trent
ON trent.TransactionID = tr.ID
INNER JOIN Item it
ON trent.ItemID = it.ID
INNER JOIN Customer c
ON c.ID=tr.CustomerID
INNER JOIN TenderEntry tent
ON tent.TransactionID = tr.ID
WHERE
tr.RecallID = 0
AND (tr.ReceiptNumber = @receiptnum OR @receiptnum IS NULL)
AND (c.accountnumber = @account OR @account IS NULL)
AND (c.FirstName = @FN OR @FN IS NULL)
AND (c.LastName = @ln OR @ln IS NULL)
AND (tr.time = @dt OR @dt IS NULL)
AND (tr.Comment LIKE @attendee + '%' OR @attendee IS NULL)
RETURN
END
备注:
- 尝试为没有值的字段传递
NULL
而不是 ''
。
- Stop using the old-style JOIN
- 也许应该是 ITVF 而不是 MTVF。
我在 java 网络应用程序中构建了一个搜索表单,如下图所示
现在,此页面的用户需要在 6 个搜索字段中的一个或多个中输入值,或者可以进行开放式搜索,将所有字段留空。
我有以下函数获取结果。
USE [KingsBayY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[test_fn_transaction_search]
(@receiptnum varchar(4001) ='',--00040401010000021
@account varchar(4001) ='',
@FN varchar(4001) ='',
@ln varchar(4001) ='',--DateTime = '',
@dt varchar(4001) ='',
@program varchar(4001) ='',--)
@attendee varchar(4001) =''
)
--stdt
--enddt
RETURNS @resulttable TABLE
(trid int,
trdate varchar(4001), --COLLATE database_default
tramount money,
trinvoice varchar(4001),
trcashierid varchar(4001),
trvoided varchar(4001),
trrecallid varchar(4001),
trrecalltype varchar(4001),
trattendee varchar(4001),
trperiod varchar(4001),
stopbilling varchar(4001),
caccount varchar(4001),
firstname varchar(4001),
lastname varchar(4001),
trprogram varchar(4001),
itemlookupcode varchar(4001),
paydate varchar(4001)
)
AS
BEGIN
IF (@receiptnum='' and @account='' and @FN=''and @ln='' and @dt='' and @program='' and @attendee='')
INSERT INTO @resulttable
select tr.ID AS [Transaction ID], tr.Time AS [trDt], tr.Total AS [amount],
tr.ReceiptNumber AS [invoice], tr.CashierID AS [cashid],
tr.Voided AS [voided], tr.RecallID AS [recallid], tr.RecallType AS [recalltype],
tr.Comment AS [attendee], tr.ReferenceNumber AS [trperiod], tr.StopBilling AS [stopbilling],
--fields from customer
c.AccountNumber AS [accountnum], c.FirstName AS [firstname], c.LastName AS [lastname],
--fields from item
it.Description AS [programname], it.ItemLookupCode AS [trItemLookupCode],
--fields from tenderentry
tent.PaymentDate AS [paydate]
from "Transaction" tr, TransactionEntry trent, Item it, Customer c, TenderEntry tent
where trent.TransactionID = tr.ID
and tent.TransactionID = tr.ID
and trent.ItemID = it.ID
and c.ID=tr.CustomerID
and tr.RecallID =0 --parent
--and tr.RecallType=0 --parent transactions and independant sales
order by tr.id, tr.time;
else IF (@receiptnum<>'' or @account<>'' or @FN<>'' or @ln<>'' or @dt<>'' or @program<>'' or @attendee<>'')
INSERT INTO @resulttable
select tr.ID AS [Transaction ID], tr.Time AS [trDt], tr.Total AS [amount],
tr.ReceiptNumber AS [invoice], tr.CashierID AS [cashid],
tr.Voided AS [voided], tr.RecallID AS [recallid], tr.RecallType AS [recalltype],
tr.Comment AS [attendee], tr.ReferenceNumber AS [trperiod], tr.StopBilling AS [stopbilling],
--fields from customer
c.AccountNumber AS [accountnum], c.FirstName AS [firstname], c.LastName AS [lastname],
--fields from item
it.Description AS [programname], it.ItemLookupCode AS [trItemLookupCode],
--fields from tenderentry
tent.PaymentDate AS [paydate]
from "Transaction" tr, TransactionEntry trent, Item it, Customer c, TenderEntry tent
where trent.TransactionID = tr.ID
and tent.TransactionID = tr.ID
and trent.ItemID = it.ID
and c.ID=tr.CustomerID
and tr.RecallID =0 --parent transactions and independant sales
--and tr.RecallType=0 --
and(
tr.ReceiptNumber=ISNULL(@receiptnum,tr.ReceiptNumber)--invoice
or c.accountnumber=ISNULL(@account,c.accountnumber)--account
or c.FirstName=ISNULL(@FN, c.FirstName)
or c.LastName=ISNULL(@ln, c.LastName)--customer
or tr.time=ISNULL(@dt,tr.time)--date
or tr.Comment=ISNULL(@attendee,tr.Comment)
--program
)
union
select tr.ID AS [Transaction ID], tr.Time AS [trDt], tr.Total AS [amount],
tr.ReceiptNumber AS [invoice], tr.CashierID AS [cashid],
tr.Voided AS [voided], tr.RecallID AS [recallid], tr.RecallType AS [recalltype],
tr.Comment AS [attendee], tr.ReferenceNumber AS [trperiod], tr.StopBilling AS [stopbilling],
--fields from customer
c.AccountNumber AS [accountnum], c.FirstName AS [firstname], c.LastName AS [lastname],
--fields from item
it.Description AS [programname], it.ItemLookupCode AS [trItemLookupCode],
--fields from tenderentry
tent.PaymentDate AS [paydate]
from "Transaction" tr, TransactionEntry trent, Item it, Customer c, TenderEntry tent
where trent.TransactionID = tr.ID
and tent.TransactionID = tr.ID
and trent.ItemID = it.ID
and c.ID=tr.CustomerID
and tr.RecallID =0 --parent transactions and independant sales
--and tr.RecallType=0 --
and(
ISNULL(tr.ReceiptNumber,'1')= ISNULL(@receiptnum,'1')--invoice
and ISNULL(c.accountnumber,'1')= ISNULL(@account,'1')--account
and ISNULL(c.FirstName,'1')= ISNULL(@FN,'1')
and ISNULL(c.LastName,'1')= ISNULL(@ln,'1')--customer
and ISNULL(tr.time,'1')= ISNULL(@dt,'1')--date
and ISNULL(tr.Comment,'1')=ISNULL(@attendee,tr.Comment)
--program
)
order by tr.id, tr.time;
RETURN
END
我从这个过程中得到了错误的结果。我注意到的问题是,
无论如何尝试搜索.. 打开搜索,指定一个搜索参数.. 指定多个搜索参数值,程序 return 的所有结果。如何根据使用的搜索参数将其编辑为 return 仅结果?
一些搜索参数可能不完全匹配..例如参加者字段..用户可能输入 'John Doe' 而 table 有参加者列其中一个单元格值为 'John Doe - the genius'.. 我希望能够搜索在单元格值中输入的术语。我该怎么做。
这是catch-all query的一种。
ALTER FUNCTION [dbo].[test_fn_transaction_search]
(
@receiptnum VARCHAR(4001) = NULL,
@account VARCHAR(4001) = NULL,
@FN VARCHAR(4001) = NULL,
@ln VARCHAR(4001) = NULL,
@dt VARCHAR(4001) = NULL,
@program VARCHAR(4001) = NULL,
@attendee VARCHAR(4001) = NULL
)
RETURNS @resulttable TABLE
(
trid INT,
trdate VARCHAR(4001),
tramount MONEY,
trinvoice VARCHAR(4001),
trcashierid VARCHAR(4001),
trvoided VARCHAR(4001),
trrecallid VARCHAR(4001),
trrecalltype VARCHAR(4001),
trattendee VARCHAR(4001),
trperiod VARCHAR(4001),
stopbilling VARCHAR(4001),
caccount VARCHAR(4001),
firstname VARCHAR(4001),
lastname VARCHAR(4001),
trprogram VARCHAR(4001),
itemlookupcode VARCHAR(4001),
paydate VARCHAR(4001)
)
AS
BEGIN
INSERT INTO @resulttable
SELECT
tr.ID AS [Transaction ID],
tr.Time AS [trDt],
tr.Total AS [amount],
tr.ReceiptNumber AS [invoice],
tr.CashierID AS [cashid],
tr.Voided AS [voided],
tr.RecallID AS [recallid],
tr.RecallType AS [recalltype],
tr.Comment AS [attendee],
tr.ReferenceNumber AS [trperiod],
tr.StopBilling AS [stopbilling],
c.AccountNumber AS [accountnum],
c.FirstName AS [firstname],
c.LastName AS [lastname],
it.Description AS [programname],
it.ItemLookupCode AS [trItemLookupCode],
tent.PaymentDate AS [paydate]
FROM [Transaction] tr
INNER JOIN TransactionEntry trent
ON trent.TransactionID = tr.ID
INNER JOIN Item it
ON trent.ItemID = it.ID
INNER JOIN Customer c
ON c.ID=tr.CustomerID
INNER JOIN TenderEntry tent
ON tent.TransactionID = tr.ID
WHERE
tr.RecallID = 0
AND (tr.ReceiptNumber = @receiptnum OR @receiptnum IS NULL)
AND (c.accountnumber = @account OR @account IS NULL)
AND (c.FirstName = @FN OR @FN IS NULL)
AND (c.LastName = @ln OR @ln IS NULL)
AND (tr.time = @dt OR @dt IS NULL)
AND (tr.Comment LIKE @attendee + '%' OR @attendee IS NULL)
RETURN
END
备注:
- 尝试为没有值的字段传递
NULL
而不是''
。 - Stop using the old-style JOIN
- 也许应该是 ITVF 而不是 MTVF。