1

我正在用 C# 编写一个程序,该程序使用传递给 sp_executesql 的参数运行一些选择语句。我在测试时遇到的一个问题是,无论我是从 SQL Profiler 还是从 Visual Studio 中的手表执行的命令,参数的值都是在语句末尾指定的,而不是在-查询中的行。出于测试目的,我想要一种将参数值替换为参数的快速方法。

所以,而不是:

exec sp_executesql N'
SELECT CustomerName
FROM CustomerTable ct WITH(NOLOCK)
WHERE ct.CustomerId <> @CustomerId
AND ct.ItemId <> @ItemId
AND ct.TransactionId = @TransactionId'
,N'@CustomerId bigint,@ItemId nvarchar(1),@TransactionId nvarchar(30), @CustomerId = 3000, @ItemId = N'4', @TransactionId=N'43281'

我想:

exec sp_executesql N'
SELECT CustomerName
FROM CustomerTable ct WITH(NOLOCK)
WHERE ct.CustomerId = 3000
AND ct.ItemId <> N'4'
AND ct.TransactionId = N'43281''

请不要过多关注示例的语法,因为它只是用于演示概念。有谁知道一个快速的方法来做到这一点?基本上,我希望将其替换为测试目的,因为这将使我更容易修改条件以测试它们如何影响返回的结果。我将不胜感激任何人都可以提供的帮助。谢谢。

4

1 回答 1

3

参数化 sp_executesql 有很多好处,包括

  • 通过显式参数化,您可以让 SQL 有机会在特定类型上缓存体面的查询计划
  • 通过参数化它有助于防止像 SQL 注入攻击这样的恶意攻击,但也避免了转义有问题的字符的需要。

因此,即使您确实设法“取消参数化”生成的 sp_executesql,如果您执行内联 sql,查询计划也可能与参数化版本有很大不同,并且您还需要进行转义等(即它不适合用于苹果与苹果测试)。

我能想到你为什么不想要参数化 sp_executesql 的唯一原因是为了便于阅读?

编辑:尝试替代将取决于您使用的技术

正如@mellamokb 建议的那样,如果您使用的是 ExecuteReader,这可能非常简单

假设您的代码类似于

string sqlCmd = "SELECT CustomerName 
FROM CustomerTable ct WITH(NOLOCK) 
WHERE ct.CustomerId <> @CustomerId 
AND ct.ItemId <> @ItemId 
AND ct.TransactionId = @TransactionId";

cmd.CommandText = sqlCmd;
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("CustomerId", DbType.Int32, myCustomerId));
cmd.Parameters.Add(new SqlParameter("ItemId", DbType.String, myItemId));
..
cmd.ExecuteReader()

然后,您可以添加代码来构建您的测试查询:

string sqlMyTest = sqlCmd.Replace("@CustomerId", myCustomerId.ToString());
sqlMyTest = sqlMyTest.Replace("@ItemId", specialEscapeFunction(myItemId));
.. do something with sqlMyTest

然而,像 Linq2SQL 或 EF 这样的 ORM 不会那么容易

customerTable.Where(c => (c.CustomerId != myCustomerId) && (c.ItemId != myItemId) && (c.TransactionId == myTransactionId))

可能像 LinqPad 这样的工具可能会有所帮助?

于 2012-03-27T18:21:54.437 回答