我要做的是创建一些带参数的任意sql命令,设置参数的值和类型,然后返回解析的sql命令 - 包含参数。我不会直接对sql数据库运行此命令,因此不需要连接。因此,如果我运行下面的示例程序,我希望看到以下文本(或类似的东西):
WITH SomeTable (SomeColumn)
AS
(
SELECT N':)'
UNION ALL
SELECT N'>:o'
UNION ALL
SELECT N'^_^'
)
SELECT SomeColumn FROM SomeTable
示例程序是:
using System;
using System.Data;
using System.Data.SqlClient;
namespace DryEraseConsole
{
class Program
{
static void Main(string[] args)
{
const string COMMAND_TEXT = @"
WITH SomeTable (SomeColumn)
AS
(
SELECT N':)'
UNION ALL
SELECT N'>:o'
UNION ALL
SELECT @Value
)
SELECT SomeColumn FROM SomeTable
";
SqlCommand cmd = new SqlCommand(COMMAND_TEXT);
cmd.CommandText = COMMAND_TEXT;
cmd.Parameters.Add(new SqlParameter
{
ParameterName = "@Value",
Size = 128,
SqlDbType = SqlDbType.NVarChar,
Value = "^_^"
});
Console.WriteLine(cmd.CommandText);
Console.ReadKey();
}
}
}
这是使用.net标准库可以实现的吗?最初的搜索说没有,但我希望我错了。
答案 0 :(得分:22)
您对参数化查询的工作方式存在错误的概念。您所说的“解析文本”是从不创建,参数值从不直接替换为查询字符串。
这就是使用参数化查询非常重要的原因 - 您从查询代码中完成查询数据的隔离。数据是数据,代码是代码,而不是twain应该满足。因此,sql注入是不可能的。
这意味着如果你有一个这样的CommandText:
SELECT SomeColumn FROM SomeTable WHERE ID= @ID
而不是最终运行如下所示的查询:
SELECT SomeColumn FROM SomeTable WHERE ID= 123
你实际上运行了更像这样的东西:
DECLARE @ID Int
Set @ID = RetrieveQueryDataItem("@ID")
SELECT SomeColumn FROM SomeTable WHERE ID= @ID
现在,这并不完全是这样;引擎不会像那样转换代码。相反,它使用sp_executesql过程。但这应该可以帮助您了解正在发生的事情。
答案 1 :(得分:3)
Joel Coehoorn是对的,它不仅仅是一个简单的字符串替换或转义字符添加等。
但是,您可以查看参数以查看您的值是否符合您的要求:
foreach (IDataParameter i in cmd.Parameters)
{
Console.WriteLine(i.Value.ToString());
}
答案 2 :(得分:2)
SQLCommand对象不会为命令文本中的值换出params并运行它。它使用您提供的确切文本调用sp_execute sql,然后提供参数列表。对数据库使用SQL分析器,你会看到我的意思。
你实际上试图在这里做什么?
答案 3 :(得分:1)
我很想调查使用LINQ因为它会在C#代码中为您提供所需的控件。