将SQL查询存储在资源文件中是不好的做法吗?

时间:2011-07-19 18:56:51

标签: asp.net sql-server visual-studio-2010

我有一个与SQL Server通信的Web应用程序。我没有硬编码所有查询字符串,而是选择将它们存储在全局资源文件中。那被认为是不好的做法吗?

另外,当我这样做时,Visual Studio会向我大吼大叫SQL注入的可能性,尽管这些查询被参数化(更不用说资源文件中的“拼写”警告)。

9 个答案:

答案 0 :(得分:10)

实践属于范围(例如避免首选使用等)并依赖于背景。

如果你从高处获得了一个不能使用存储过程的任务,你也不能使用ORM,那么将复杂的SQL存储为资源并不是一种实践,因为你至少没有逃避System.String中的角色,至少让你保持一定的安全。如果您的SQL本质上是动态的,那么将资源文件与文本模板机制相结合是相当干净的。

尽管如此,除非在维护成本,可读性和功能方面有明显的好处,否则应该避免使用资源文件的(通常在大多数情况下)。将存储过程绑定到代码有很多简洁的方法;有许多称职的ORM工具和小型数据访问层可能会做得更好。

答案 1 :(得分:8)

将SQL查询与应用程序代码分开是一件好事。存储过程是执行此操作的常规方法,但如果这不可行并且您必须直接使用SQL,我认为您的方法很好。最新版本的SQL Server参数化查询在第一次运行时进行预编译,并提供与SP类似的性能。

我建议你研究其他数据访问方法,例如linq-to-sql,它可以自动生成SQL查询,并为代码提供更清晰的界面。

答案 2 :(得分:5)

资源文件definitley不是这个地方。资源文件的要点是可以本地化的事物的集中存储库(即被其他语言/文化定义的其他资源文件覆盖)。

例如,您在"Hello"中添加了字符X.resources.dll,但您也可以为西班牙语创建es-ES\X.resources.dll,其中字符串会显示"Hola"而不是 - 当你的应用程序查询字符串时,它将获得与用户操作系统配置的语言/文化相匹配的任何版本。

如果您希望在不重新编译代码的情况下轻松更改SQL,请将其放在App.config中并使用ConfigurationManager类将其读出。如果您不希望在没有代码重新编译的情况下更改它,只需将该事物硬编码为static / const string。也就是说,理想当然是制作真正的存储过程。

答案 3 :(得分:4)

我认为很多人认为硬编码SQL是一种不好的做法,无论它是如何存储的......: - )

我将假设有一些令人信服的理由不使用Linq to SQL,Entity Framework或其他ORM工具?

如果你必须在你的应用程序中使用硬编码SQL,那么会认为它在你的代码中是更好的内联,因为它使你的代码更具可读性,因此更易于维护......

答案 4 :(得分:3)

这样做我没有看到任何特别“坏”的东西。它实际上与在代码中对sql代码进行硬编码没什么不同,只是与在运行时生成SQL ad-hoc的情况略有不同。

您说您正在使用参数化查询,因此您不必担心脚本注入。

如果要将sql存储在资源文件中以遵守DRY原则,那么您可能希望使用某种DAL来实现此目的。像实体框架(EF)或Linq-to-SQL

答案 5 :(得分:3)

我使用这种模式构建了一个应用程序 - 在PHP中,而不是.Net,但原则是相同的。

<强>优点:

  • 我可以轻松找到单个文件中所需的所有SQL。这有助于处理数据库问题(应用程序的任何部分是否实际使用此表?我们有多少查询更新表z?)。
  • 我可以轻松更新SQL而无需更改其余代码。

<强>缺点:

  • 这使得其余代码更难调试 - 如果从数据库返回的数据存在问题,我必须查看两个地方。许多资源键非常相似,导致一些有趣的wtf时刻。
  • 在实践中,我从未在不更改其余代码的情况下更新SQL。

根据我的经验,这些好处不会与缺点相悖。

BTW - 许多缺点也适用于存储过程。使用存储过程有一个很好的例子 - 但是同样好的情况是不使用它们。

答案 6 :(得分:1)

这不一定是不好的做法,但如果需要打开另一个文件并找到正确的密钥,它会让您更难读取程序。

Visual Studio抱怨,因为它无法看到该值是常量,并且它始终来自可靠来源。

在源文件中使用SQL不会比在源文件中包含其余程序代码更“硬编码”。你为什么要这样做呢?要重新使用查询?也许你应该考虑商店程序......

答案 7 :(得分:0)

我想到的是,这只会给代码增加不必要的复杂性。

是的,您可以将查询保留在资源文件中。或者,为了确保在部署项目后没有人与他们混淆,您可以加密它们并将它们存储在文件中。或者更好的是,你可以对它们进行加密,然后将它们存储在一个数据库中,以便没有人能够访问这台机器。

但最终,我不得不问,重点是什么?只需对它们进行硬编码即可完成。

KISS。

答案 8 :(得分:0)

您可以编写存储过程并在代码中调用它们,而不是读取存储在外部的查询。