如何使用 SqlCommand 创建带有参数化数据库名称的数据库?
简而言之。我有两个简单的助手:
private SqlCommand CreateCommand(string text)
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = text;
return cmd;
}
void SetParameter(SqlCommand cmd, string p, string dbName)
{
cmd.Parameters.Add(p, SqlDbType.NVarChar);
cmd.Parameters[p].Value = dbName;
}
这个执行正常:
var cmd = CreateCommand("CREATE DATABASE Demo "+
@"ON (FILENAME = N'c:\demo_data.mdf') "+
@"LOG ON (FILENAME = N'c:\demo_data.mdf.LDF') "+
"FOR ATTACH " +
"GO");
cmd.ExecuteNonQuery();
但是这个不行:
string dataBaseAttachText = "CREATE DATABASE @dbname " +
"ON (FILENAME = @filename) " +
"LOG ON (FILENAME = @filenamelog) " +
"FOR ATTACH GO";
var cmd = CreateCommand(dataBaseAttachText);
SetParameter(cmd, "@dbname", "Demo");
SetParameter(cmd, "@filename", @"c:\demo_data.mdf");
SetParameter(cmd, "@filenamelog", @"c:\demo_data.mdf.LDF");
cmd.ExecuteNonQuery();
为什么?
To put it short. I've got two simple helpers:
private SqlCommand CreateCommand(string text)
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = text;
return cmd;
}
void SetParameter(SqlCommand cmd, string p, string dbName)
{
cmd.Parameters.Add(p, SqlDbType.NVarChar);
cmd.Parameters[p].Value = dbName;
}
This executes OK:
var cmd = CreateCommand("CREATE DATABASE Demo "+
@"ON (FILENAME = N'c:\demo_data.mdf') "+
@"LOG ON (FILENAME = N'c:\demo_data.mdf.LDF') "+
"FOR ATTACH " +
"GO");
cmd.ExecuteNonQuery();
But this doesn't:
string dataBaseAttachText = "CREATE DATABASE @dbname " +
"ON (FILENAME = @filename) " +
"LOG ON (FILENAME = @filenamelog) " +
"FOR ATTACH GO";
var cmd = CreateCommand(dataBaseAttachText);
SetParameter(cmd, "@dbname", "Demo");
SetParameter(cmd, "@filename", @"c:\demo_data.mdf");
SetParameter(cmd, "@filenamelog", @"c:\demo_data.mdf.LDF");
cmd.ExecuteNonQuery();
Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
DML 操作支持参数,但 DDL 操作不支持参数,DDL 操作没有执行计划。您将需要使用动态 SQL
DDL = 数据定义语言(创建、删除、更改...)
DML = 数据操作语言(选择、更新、删除、插入)
Parameters are supported for DML operations not DDL operations, there are no execution plans for DDL operations. you will need to use dynamic SQL
DDL = Data Definition Language (create, drop, alter....)
DML = Data Manipulation Language (select, update, delete, insert)
遗憾的是,您可以通过将 DDL 操作包装在 DML 操作中来实现此目的。
Sadly you can accomplish this by wrapping your DDL operation in a DML operation.
您只能在 SQL Server 支持的地方使用参数。不幸的是,SQL Server 不支持参数化的
CREATE DATABASE
语句(尽管我感觉文件名部分可能支持参数)。您需要自己构建 SQL:
注意:这很容易受到 SQL 注入攻击,因此必须小心;如果您不信任数据库名称的来源,请不要这样做!
如果文件名部分也无法参数化,则需要对这些部分进行类似的更改。
You can only use parameters in places where SQL Server supports them. Unfortunately SQL Server does not support parameterised
CREATE DATABASE
statements (although I have a feeling the filename parts may support parameters).You'll need to construct the SQL yourself:
CAUTION: this is susceptable to SQL-injection attacks so caremust be taken; if you don't trust the source of the database name, don't do this!
You'll need to make similar changes to the filename parts if those can't be parameterised either.
作为丹尼尔和里奇答案的结合。通过运行 DML 查询
sp_executesql
您也可以使用QUOTENAME
它应该逃避任何可能传入的 sql 注入尝试。这应该使用传递的正确参数执行以下 DML sql 查询。
As a bit of a combination of both Daniel's and Rich's answer. By running a DML query to
sp_executesql
you can have a dynamically built query, also by usingQUOTENAME
it should escape any attempts at sql injection someone may pass in.This should execute the following DML sql query with the proper parameters passed.
我通过创建一个扩展方法来适当地包装所有实体来解决这个问题。
用法:
I solved this problem by creating an extension method to wrap all entities appropriately.
Usage:
我通过调用存储过程“sp_executesql”中的构建来解决此任务。
用于创建数据库的连接字符串指向“master”。
完整的SQL语句是参数值的一部分:
I solved this task by calling the build in stored precedure 'sp_executesql'.
The connectionstring used to create DB points to 'master'.
The complete SQL statement is part of parameter value: