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