搜索页面的 SQL 查询
Posted
技术标签:
【中文标题】搜索页面的 SQL 查询【英文标题】:SQL Query for Search Page 【发布时间】:2019-07-31 16:56:47 【问题描述】:我正在为一个在线数据库课程做一个小项目,我想知道你是否可以帮助我解决我遇到的问题。
我有一个网页正在搜索电影数据库并使用电影初始输入字段、数字输入字段和代码字段检索特定列。这些都将转换为字符串并用作查询的用户输入。
以下是我之前尝试过的:
select A.CD, A.INIT, A.NBR, A.STN, A.ST, A.CRET_ID, A.CMNT, A.DT
from MOVIE_ONE A
where A.INIT = :init
AND A.CD = :cd
AND A.NBR = :num
页面必须搜索的方式有三种不同的情况:
-
(首字母和编号)
(代码)
(首字母和号码和代码)
案例必须是独立的,因此如果某个字段为空,但满足某个案例,则搜索通过。它也必须在一个查询中。我被困在如何实施这些案例上。
查询中的参数取自 SQLJ 文件中方法中的 Java 参数。
如果您能就我如何解决这个问题提供一些帮助,我将不胜感激!
【问题讨论】:
您需要使用特定的 SQL RDBMS 来标记您的问题,但通常如果参数为空,您的where
子句中的每个条件都会返回 true;例如(A.INIT = :init or :init is null) and (A.CD = :cd or :cd is null)
之类的东西。
我确定这是一个错字,但是您的 select 子句中有一个名为 A.NBR 的字段,而您的 where 子句中有一个名为 A._NBR 的字段,我怀疑它们指的是相同的字段。
【参考方案1】:
考虑将等式表达式包装在NVL
(与COALESCE
同义)中,因此如果参数输入为空,则会根据自身检查相应的列。另外,一定要踢a-b-c table aliasing habit。
SELECT m.CD, m.INIT, m.NBR, m.STN, m.ST, m.CRET_ID, m.CMNT, m.DT
FROM MOVIE_ONE m
WHERE m.INIT = NVL(:init, m.INIT)
AND m.CD = NVL(:cd, m.CD)
AND m.NBR = COALESCE(:num, m.NBR)
为了演示,考虑下面的 DB2 fiddles,其中每个案例都可以通过调整值 CTE 参数来检查,这些参数都在相同的精确数据上运行。
Case 1
WITH
i(init) AS (VALUES('db2')),
c(cd) AS (VALUES(NULL)),
n(num) AS (VALUES(53)),
cte AS
...
Case 2
WITH
i(init) AS (VALUES(NULL)),
c(cd) AS (VALUES(2018)),
n(num) AS (VALUES(NULL)),
cte AS
...
Case 3
WITH
i(init) AS (VALUES('db2')),
c(cd) AS (VALUES(2018)),
n(num) AS (VALUES(53)),
cte AS
...
但是,请注意,由于数据的性质(即双精度和日期),小提琴运行不同的 SQL。但是查询确实反映了相同的概念,NVL
双方都匹配表达式。
SELECT *
FROM cte, i, c, n
WHERE cte.mytype = NVL(i.init, cte.mytype)
AND YEAR(CAST(cte.mydate AS date)) = NVL(c.cd, YEAR(CAST(cte.mydate AS date)))
AND ROUND(cte.mynum, 0) = NVL(n.num, ROUND(cte.mynum, 0));
【讨论】:
感谢您的意见!我已经根据您的回答进行了尝试,它返回了案例 1 和 2 的所需输出。案例 3 返回案例 2 的输出,我假设它应该这样做。我想它会返回一行匹配所有三个参数 应该的。仔细检查所有三个参数是否为空并仔细检查结果。发布您提交的内容和案例 3 的结果。 实际上,这个答案确实返回了案例 3 的输出。但对于案例 1 和 2,它不返回任何内容。如果我将答案切换为:where (m.INIT = NVL(:init, m.INIT) AND m.NBR = COALESCE(:num, m.NBR)) OR m.CD = NVL(:cd, m.CD)
,它将返回案例 1 和 2,但不返回案例 3。@Parfait
请再次发布您传递的参数和您收到的结果。我添加了一个演示来显示所有案例返回条件结果,具体取决于参数是否为NULL
。可能您发布的内容比实际内容更简化。确保表达式匹配双方。例如,如果 cd 是日期并且您想匹配年份:AND Year(m.CD) = NVL(:cd, Year(m.CD))
.
另外,我不熟悉 IBM 的 SQLJ
库,因为它处理 NULL
的方式似乎与通常的应用程序参数不同。见examples here。如果您应该使用流行的 Java、C#、php、Python、VB DB-API 连接到您的 DB2 并将这些参数传递给准备好的 SQL 语句,我保证这个逻辑应该有效。以上是关于搜索页面的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章