带有定义的子查询

问题描述

带有定义的子查询

你好

我有一个问题,关于在实际中使用 DEFINE。

我刚刚修改了讲座中的代码,在开始时定义了我们正在与之合作的员工,然后在代码中使用定义的变量,如下所示:

DEFINE employee = "(select * from employees where employee_id = 145)";
 
-- all employees that work in the same departmant as 'defined employee'
SELECT *
FROM   employees
WHERE  department_id = (
                        SELECT department_id 
                        FROM   &employee        -- here using that variable
                        );

这个解决方案聪明吗?这是你在现实生活中会做的事情吗?

我的意思是,如果我们对同一个人有很多查询,那么稍后我们不必更改每个查询,因为我们将不得不更改 employee_id ,我们只需更改定义变量中的 id 即可,一切仍然有效。

或者我应该定义更多变量,例如:

定义工资 = ...

定义部门 = ...

为了内存优化,所以我们不返回所有员工的信息,而是只返回我们真正需要的信息?

问候

解决方法

好主意,但不是最好的实施方式。 Google 搜索“SQL 注入”以查看原因之一。

更好:为您“定义”的 select 语句使用视图,并在需要时引用该视图。并使用绑定变量(谷歌找到教你如何使用绑定变量的链接)用于员工 ID 或部门等内容。这将防止 SQL 注入,并且效率更高因为每次输入更改时都不需要重新编译查询(这会在您的方法中发生)。

,

DEFINE 是一个简单替换的 SQL*Plus 命令。它与 SQL 语言无关。它不能用于通过例如 ODBC 或 JDBC 的查询,因此它的实际使用受到您自己工作自动化的限制,当您可能有一堆自己喜欢的准备好的脚本并希望对它们进行参数化以提高灵活性。

如果您通过 SQL*Plus 进行连接,那么您已经拥有数据库凭据并且已经可以在数据库中执行很多操作,因此这不适用于最终用户。

这是关于这个主题的好文章:SQL*Plus Substitution Variables - DEFINE variables and parameters in SQL Queries

要使用用户输入,您需要绑定变量:它们接受数据,而不是一些和平的文本,并且永远不会与关键字、标识符、函数等 SQL 标记混合。

所以结论是:如果你觉得把它用于你自己的日常任务,那可能没问题。但不能发布给用户。