我正在用C#编写一个程序,它使用传递给sp_executesql的参数运行一些select语句。我在测试时遇到的一个问题是,无论是从SQL事件探查器执行命令还是从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''
请不要过多关注示例的语法,因为它只是用来演示这个概念。有谁知道这样做的快速方法?基本上,我希望将它替换为测试目的,因为它将使我更容易修改条件以测试它们如何影响返回的结果。我很感激任何人都可以给予的帮助。感谢。
答案 0 :(得分:3)
参数化的sp_executesql有许多好处,包括
因此,即使您设法对生成的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这样的工具可能有帮助吗?