Действительно ли возможно получить проанализированный текст 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? Начальный поиск говорит "нет", но я надеюсь, что я неправ.

15
задан Burg 7 May 2010 в 14:53
поделиться

4 ответа

Вы ошибочно представляете, как работают параметризованные запросы. "Анализируемый текст", о котором вы говорите, никогда не создается, а значения параметров никогда не подставляются непосредственно в строку запроса.

Вот почему так важно использовать параметризованные запросы - у вас есть полное отделение данных запроса от кода запроса. Данные есть данные, код есть код, и они никогда не встретятся. Таким образом, нет возможности для 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. Но это должно помочь вам понять, что происходит.

22
ответ дан 1 December 2019 в 02:28
поделиться

Joel Coehoorn прав, это не простая подстановка строк или добавление управляющих символов и т.д.

Вы можете, однако, просмотреть свои параметры, чтобы убедиться, что ваши значения соответствуют желаемым:

foreach (IDataParameter i in cmd.Parameters)
{
    Console.WriteLine(i.Value.ToString());
}
3
ответ дан 1 December 2019 в 02:28
поделиться

Объект SQLCommand не заменяет параметры значения в тексте команды и не запускает его. Он вызывает sp_execute sql с точным текстом, который вы вводите, а затем предоставляет список параметров. Используйте профилировщик SQL для базы данных, и вы поймете, что я имею в виду.

Чего вы на самом деле пытаетесь достичь здесь?

2
ответ дан 1 December 2019 в 02:28
поделиться

У меня возникнет соблазн изучить возможность использования LINQ , поскольку это даст вам необходимый контроль в вашем коде C #.

1
ответ дан 1 December 2019 в 02:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: