Можно ли получить анализируемый текст 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 ответов
у вас есть ошибочное представление о том, как работают параметризованные запросы. "Разобранный текст", о котором вы говорите, это никогда создано, а значения параметров -никогда заменен непосредственно в строку запроса.
вот почему так важно использовать параметризованные запросы - у вас есть полное разделение данных запроса из кода запроса. Данные есть данные, код есть код, и никогда они не встретятся. Таким образом, нет возможности для 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. Но это должно помочь вам понять, что происходит.
Джоэл Кохорн прав, это не просто простая подстановка строк или добавление escape-символов и т. д.
вы можете, однако, просмотреть свои параметры, чтобы увидеть, если ваши значения, как вы хотите их:
foreach (IDataParameter i in cmd.Parameters)
{
Console.WriteLine(i.Value.ToString());
}
объект SQLCommand не заменяет параметры для значения в тексте команды и не запускает его. Он вызывает sp_execute sql с точным текстом, который вы предоставляете, а затем предоставляет список параметров. Используйте SQL profiler против базы данных, и вы увидите, что я имею в виду.
Что вы на самом деле пытаетесь достичь здесь?
Я бы соблазнился посмотреть на использование LINQ поскольку это даст вам элемент управления, который вы хотите в своем коде C#.