【发布时间】:2009-07-20 12:01:48
【问题描述】:
我有一个选择查询,它根据用户输入获取一些值,例如:-
SELECT
company, accounts
from testdrive
WHERE company LIKE '&Company', accounts = '&Account'
order by company desc
在 Toad 中运行时,系统会提示用户输入值。但我想知道 USER 如何将“条件”与值一起指定?检测 >、
【问题讨论】:
我有一个选择查询,它根据用户输入获取一些值,例如:-
SELECT
company, accounts
from testdrive
WHERE company LIKE '&Company', accounts = '&Account'
order by company desc
在 Toad 中运行时,系统会提示用户输入值。但我想知道 USER 如何将“条件”与值一起指定?检测 >、
【问题讨论】:
我不是 TOAD 用户,但看起来 TOAD 只是依赖于 SQLPlus 的替换变量功能。 SQLPlus 替换变量不是绑定变量——它们只是愚蠢的字符串替换——所以你可以在其中放入任何你想要的东西。既然如此,你有没有看到如果你这样做会发生什么:
SELECT company
, accounts
FROM testdrive
WHERE company &Company_Comparison '&Company'
AND accounts &Account_Comparison '&Account'
ORDER BY company DESC;
应提示用户输入 Company_Comparison 和 Account_Comparison,他们可以在其中输入 !=、LIKE 等。当然,您将无法验证他们的输入,并且这样的事情很容易受到 SQL 注入攻击,但由于您的客户是 TOAD,我认为您并不是真的在寻找防弹解决方案。
【讨论】:
他不能。为此,您需要动态 sql。
【讨论】:
为接受运算符作为参数的每一列编写一个函数。这样,可以通过绑定变量以及操作数本身来提供运算符。然而,这种方法可能会遇到性能问题,因为优化器根本无法很好地计算谓词的选择性。
例如
FUNCTION company_is (company IN VARCHAR2, op IN VARCHAR2, value IN VARCHAR2) IS
BEGIN
RETURN CASE op
WHEN '=' THEN (company = value)
WHEN 'LIKE' THEN (company LIKE value)
WHEN '<' THEN (company < value)
...
END;
END;
FUNCTION date_is (thedate IN DATE, op IN VARCHAR2, value IN DATE) IS
BEGIN
RETURN CASE op
WHEN '=' THEN (thedate = value)
WHEN '<' THEN (thedate < value)
...
END;
END;
那么你可以通过这种方式提供谓词:
SELECT company, accounts
FROM testdrive AS t
WHERE company_is(t.company,'&CompanyOp','&Company')
AND date_is(t.date_created,'&CreatedOp',TO_DATE('&Created','DD/MM/YYYY'))
ORDER BY company DESC
但请注意性能问题 - 除非您可以以正常方式指定其他谓词,否则您只会看到完整扫描!
【讨论】:
没有直接的方法可以做到这一点。
对于简单的情况,您可以通过为不同的比较提供多个参数来解决此限制。
例如
SELECT company, accounts from testdrive WHERE company LIKE '&Company', accounts = '&Account' AND date<&datesmaller AND date<=&datesmallerequal order by company desc
等等。然后您可以同时提供 datesmaller 和 datesmallerequal。只需将您不需要的日期设置为遥远的未来,条件将无济于事。
但这仅适用于简单的情况,通常您需要动态 SQL 或存储过程(可以在内部处理复杂的参数)。
【讨论】: