Inline SQL硬编码吗?

时间:2011-03-14 19:58:38

标签: sql

我听过一些强大的开发人员说“内联SQL本身并不邪恶”。我不明白内联SQL是如何被接受的。对我而言就像硬编码一样。许多开发人员会嘲笑我在代码和配置文件中放置连接字符串。那么为什么“SELECT value1,value2 FROM TABLE”在编译代码中是完全可以接受的呢?

8 个答案:

答案 0 :(得分:6)

我认为数据库查询围绕它的代码之间存在很多耦合。例如,查询可能从数据库中获取特定用户的名字和姓氏,然后创建包含名字和姓氏的XML文件。

如果您将数据库查询放在其他位置(例如配置文件),您似乎可以增加可配置性和灵活性。但是,如果要实际更改它,比如在XML文件中添加一个名为“age”的字段,则不能单独更改查询,而是需要更改编写XML文件的代码。所以实际上你已经取代了必须改变一段代码的问题,不得不改变两件事(代码和配置)的问题,以及它们可能不一致的危险,而你还没有获得任何代码。额外的灵活性。

(如果看起来人们可以编写通用代码来获取所有数据库字段并将它们放在XML文件中,请考虑将年龄存储为数据库中的出生年份的情况,并且您必须进行计算才能创建年龄。)

答案 1 :(得分:6)

当我看到程序员的长度只是为了避免简单的查询,如:

select * from products where productid in (1,2) and productactive = 1

或:

select * from products where not exists (
    select * from order_lines where products.id = order_lines.productid)

然后我总是想知道他们的真正目标是什么。因为它不能简单。

答案 2 :(得分:3)

SQL是代码,它与其他代码的编程语言不同。如果您需要更改SQL,您通常也需要更改处理该SQL,数据和数据库模式的代码。 SQL在安装之间不应该有所不同。

如果添加列,更改SQL是不够的,您还需要更改处理该列的代码。几乎任何对数据库模式和SQL的更改,仅仅更改SQL是不够的。

另一方面,连接字符串是配置,而不是代码。

(是的,所有这些都有例外,如果您正在创建通用报告工具,则需要对其进行设计,以便SQL可以“配置”)

答案 3 :(得分:2)

SQL查询是代码,而不是配置。

在敏捷环境中,在SQL Server等动态编译的系统上使用存储过程非常有用,因为您可以通过修补存储过程来修复或解决应用程序问题。

但它仍然是代码。

答案 4 :(得分:2)

另一个区别(除了代码与配置之外)是连接字符串可能在整个代码库中使用,而SQL查询更可能与特定的类或方法耦合。因此,如果您订阅“不要重复自己”,您肯定会从集中连接字符串中受益,但是将SQL字符串移动到其他位置可能无法获得任何好处。

话虽这么说,一些最优雅的解决方案涉及完全通过使用Hibernate或其他ORM来避免SQL字符串,但这是一个不同的主题。

答案 5 :(得分:1)

编译代码中的“SELECT value1,value2 FROM TABLE”是所谓的Object-relational impedance mismatch的本质。自LINQ发布以来,绝大多数情况下不再接受内联SQL ......

答案 6 :(得分:1)

我已经制作了所有SQL都在存储过程中的系统,存储过程的名称本身甚至都没有存储在程序中,而是存储在app.config中。

这意味着不仅可以修补存储过程,而且不同的客户可以使用不同的过程。

提供给应用程序的数据库服务接口因此是系统设计的一部分。

在客户端应用程序中拥有任何SQL(包括基于表的ORM和LINQ)的缺点是您几乎没有明确的安全接口。使用存储过程,只有一个GRANT - EXEC。对于表或甚至视图,ORM将需要SELECT,UPDATE,INSERT,DELETE用于工具生成或存储在应用程序中的任何SQL。对系统正常运行和能够进行审计所需的权利进行盘点比拥有一个完整的存储过程层(以及在某种程度上,只读视图)要困难得多。

所以我会说“SELECT value1,value2 FROM TABLE”在客户端代码中是不可接受的,因为每个可能执行该语句的用户需要在基表的那两列上使用SELECT,这很难管理,甚至角色。

答案 7 :(得分:1)

查看它的一种方法是将表名和列名视为数据库“公共”接口的一部分。这就是数据库实现物理数据独立性的方式。可更新视图在某种程度上实现了逻辑数据的独立性。