是否可以使用SqlParameters获取SqlCommand的已解析文本?

时间:2010-05-07 14:53:56

标签: c# sql-server sqlcommand sqlparameters

我要做的是创建一些带参数的任意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标准库可以实现的吗?最初的搜索说没有,但我希望我错了。

4 个答案:

答案 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#代码中为您提供所需的控件。