【问题标题】:Can I execute SQL with parameters from within Visual Studio?我可以使用 Visual Studio 中的参数执行 SQL 吗?
【发布时间】:2017-12-11 20:02:40
【问题描述】:

编辑:从 cmets 来看,我一直不清楚我想要实现的目标。我换个角度试试。

多年来,我一直在开发存储过程。我越来越觉得在 C# 代码中嵌入的 SQL 和存储过程之间进行选择都是不好的选择。我知道很多人会不同意,这很好。 我没有在问题中详细说明这一点,以避免讨论是否关于 sprocs :-)。

作为一项实验,我尝试在 Visual Studio 的项目中嵌入 .sql 文件。从字面上看,在我的项目树中,我有带有.sql 扩展名和Build Action 设置为Embedded Resource 的文件。

这样我就可以在 VS 中编辑 SQL 查询代码,甚至可以在 VS 中运行/执行它,而无需运行项目。我喜欢那个。我现在正在处理的实际代码类似于具有分页和多个排序和过滤选项的“产品列表”。 SQL 查询具有@skip@search 等参数。这意味着如果我尝试从 VS 中运行/执行它(特别是通过按 CTRL + SHIFT + e 或从 VS 的“SQL”菜单中选择“执行” ) 这些参数丢失了(当然),因为它们应该在运行时以SqlParameter 的形式提供。我理解为什么会发生这种情况,并且绝不打算暗示 VS 或 SSMS 被窃听。我只是在寻找一种方法来“告诉”VS“当我在 VS 中执行此查询时,我打算将 @skip 设为 10”。我(可能是错误地)假设 VS 具有 IntelliSense 支持和对 .sql 文件的执行支持的原因是为了支持类似于我正在尝试的场景)。

我只是希望其他人也在做同样的事情,并且有一个聪明的方式/插件/技巧来支持它。

编辑结束

在 Visual Studio 2017 的一个项目中,我有许多 .sql 文件,这些文件在构建时嵌入到应用程序中。
在 VS 中编辑文件时,我可以方便地连接到 SQL 服务器并执行查询。
但是,如果查询有这样的参数:

SELECT * FROM Employee WHERE ID=@ID;

在 Visual Studio 中执行失败并显示

Must declare the scalar variable "@ID".

这可以通过在脚本/文件的顶部添加一行来“修复”,所以它看起来像:

DECLARE @ID int = 123;
SELECT * FROM Employee WHERE ID=@ID;

但是,现在从这样的代码中调用它时它不起作用(使用 Dapper,它与问题无关,但解释了语法):

var emp = conn.Query<Employee>( sql, new { ID=123 } );

我希望我可以在不在文件中的某处指定 ID 的值,或者指定 VS 将执行的文件的某些部分,但稍后从代码调用时会被忽略。

编辑:明确地说,我可以制作 SQL 以便它在运行时在 Visual Studio 中完美运行,但我不能同时拥有这两者。我希望有一些巧妙的技巧,一个 VS 插件或只是一些我刚刚缺少的 VS 功能。我考虑过添加一个简单的预处理器,这样我就可以做这样的事情:

--if DEBUG
DECLARE @ID int = 123;
--endif
SELECT * FROM Employee WHERE ID=@ID;

然后我可以将它添加到加载嵌入资源的函数中。

【问题讨论】:

  • 不能将服务器上的 SQL 存储为存储过程吗?
  • 我可以但宁愿避免它。我们还没有找到令人满意的数据库版本控制解决方案,所以我宁愿不在数据库中存储代码。此外,这将如何帮助我在 VS 中编辑和执行它?
  • @AlexK。存储过程是一个无关的讨论;有时有效,有时无效——但很简单:无关:blog.marcgravell.com/2017/12/…(参见:第二部分)
  • “但是,现在从这样的代码中调用它时它不起作用” - 发生了什么sql 是您期望的值吗?只要sql 是您问题中的字符串,您所显示的应该可以正常工作。 Dapper 不关心字符串 来自何处。它只关心字符串 包含的内容 - 所以:sql 的值是什么?

标签: sql-server visual-studio


【解决方案1】:

如果我对问题的理解有误,请见谅。难道你正在寻找这样的东西?查询方法实际上并不重要,看起来问题在于当您实际上必须将替换添加到脚本本身时,您将其声明为@ID

con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = "SELECT * FROM Employee WHERE ID=@ID;";
cmd.Parameters.Add("@ID", actualID); <--this is is why declaring doesn't work - You can declare it, but you also need to add it to the query
SqlDataReader rdr = cmd.ExecuteReader();

【讨论】:

  • 注意:这里的一切都是 Dapper(问题中显示的代码)已经完成的。因此,虽然此答案中的代码没有任何错误 - 它也不会改变问题中的任何内容
  • 我的意思是,您示例中的 SQL 不能从 VS 或 SSMS 中执行,它会抱怨 @ID 未声明。在我的实际代码中,CommandText 可能有 50 行长,并且驻留在扩展名为 .sql 的文件中。我可以通过 SQL -&gt; Execute 菜单在 VS 中针对 Sql Server 轻松执行此文件,但前提是没有未声明的参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-12
  • 1970-01-01
  • 2019-06-05
  • 2020-02-28
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多