2008-08-18 4 views
6

.NET, Java и другие API баз данных высокого уровня на разных языках часто предоставляют методы, известные как подготовленные операторы и привязки параметров, а не отправка текстовых команд на сервер базы данных. То, что я хотел бы знать, что происходит, когда вы выполняете такое заявление:Параметр привязки: что происходит под капотом?

SqlCommand cmd = new SqlCommand("GetMemberByID"); 
cmd.CommandType = CommandType.StoredProcedure; 
SqlParameter param = new SqlParameter("@ID", memberID); 
para.DbType = DbType.Integer; 
cmd.Parameters.Add(param); 

Я знаю, что это лучшая практика. Атаки SQL-инъекций сведены к минимуму таким образом. Но что именно происходит под капотом при выполнении этих утверждений? Является ли конечный результат еще безопасной строкой SQL? Если нет, каков конечный результат? И достаточно ли этого, чтобы предотвратить атаки SQL-инъекций?

ответ

5

The MySQL manual page В подготовленных заявлениях содержится много информации (которая должна применяться к любой другой СУБД).

В принципе, ваш оператор анализируется и обрабатывается досрочно, а параметры отправляются отдельно, а не обрабатываются вместе с кодом SQL. Это устраняет атаки SQL-инъекций, поскольку SQL анализируется до того, как параметры будут установлены.

0

Если вы используете MS SQL, загрузите профайлер, и вы увидите, какие SQL-команды генерируются при использовании параметризованных запросов. Вот пример (я использую Enterprise Libary 3.1, но результаты те же, используя SqlParameters непосредственно) с SQL Server 2005:

string sql = "SELECT * FROM tblDomains WHERE DomainName = @DomName AND DomainID = @Did"; 
Database db = DatabaseFactory.CreateDatabase(); 
using(DbCommand cmd = db.GetSqlStringCommand(sql)) 
{ 
    db.AddInParameter(cmd, "DomName", DbType.String, "xxxxx.net"); 
    db.AddInParameter(cmd, "Did", DbType.Int32, 500204); 

    DataSet ds = db.ExecuteDataSet(cmd); 
} 

Это создает:

exec sp[underscore]executesql N'SELECT * FROM tblDomains WHERE DomainName = @DomName AND DomainID = @Did', 
    N'@DomName nvarchar(9), 
    @Did int', 
    @DomName=N'xxxxx.net', 
    @Did=500204 

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

db.AddInParameter(cmd, "DomName", DbType.String, "'xxxxx.net"); 

exec sp[underscore]executesql N'SELECT * FROM tblDomains WHERE DomainName = @DomName AND DomainID = @Did', 
    N'@DomName nvarchar(10), 
    @Did int', 
    @DomName=N'''xxxxx.net', 
    @Did=500204 
0

в неспециалист условия: если посылается подготовленный оператор, то DB будет использовать план, если он доступен, он не не должны воссоздать план каждый раз, когда этот запрос отправляется, но изменились только значения параметров. это очень похоже на то, как работает procs, дополнительное преимущество с procs заключается в том, что вы можете давать разрешение только через procs, а не под базовые таблицы вообще

Смежные вопросы