Mik*_*lov 16 c# sql-server ado.net
简而言之.我有两个简单的助手:
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;
}
Run Code Online (Sandbox Code Playgroud)
这执行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();
Run Code Online (Sandbox Code Playgroud)
但这不是:
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();
Run Code Online (Sandbox Code Playgroud)
为什么?
SQL*_*ace 20
DML操作支持参数而不支持DDL操作,DDL操作没有执行计划.您将需要使用动态SQL
DDL =数据定义语言(创建,删除,更改....)
DML =数据操作语言(选择,更新,删除,插入)
Dan*_*haw 10
您只能在SQL Server支持它们的位置使用参数.不幸的是SQL Server不支持参数化CREATE DATABASE语句(虽然我觉得文件名部分可能支持参数).
您需要自己构建SQL:
string dataBaseAttachText = "CREATE DATABASE [" + dbName + "] " +
"ON (FILENAME = @filename) " +
"LOG ON (FILENAME = @filenamelog) " +
"FOR ATTACH GO";
var cmd = CreateCommand(dataBaseAttachText);
SetParameter(cmd, "@filename", @"c:\demo_data.mdf");
SetParameter(cmd, "@filenamelog", @"c:\demo_data.mdf.LDF");
cmd.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)
注意:这对SQL注入攻击是可以接受的,因此必须小心谨慎; 如果您不信任数据库名称的来源,请不要这样做!
如果不能对参数化进行参数化,则需要对文件名部分进行类似的更改.
小智 9
遗憾的是,您可以通过在DML操作中包装DDL操作来实现此目的.
var createDatabaseQuery = "exec ('CREATE DATABASE ' + @databaseName)";
var sqlCommand = new SqlCommand(createDatabaseQuery, sqlConnection);
sqlCommand.Parameters.Add("@databaseName", SqlDbType.Text);
sqlCommand.Parameters["@databaseName"].Value = "HelloWorld";
sqlCommand.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)
作为丹尼尔和里奇答案的结合。通过运行 DML 查询,sp_executesql您可以拥有动态构建的查询,也可以通过使用QUOTENAME它来避免任何人可能传入的 sql 注入尝试。
string dataBaseAttachText = @"
DECLARE @SQLString nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);
SET @SQLString =
N'CREATE DATABASE ' + QUOTENAME(@dbName) + N'
ON (FILENAME = @filename)
LOG ON (FILENAME = @filenamelog)
FOR ATTACH GO'
SET ParmDefinition = N'@filename nvarchar(MAX), @filenamelog nvarchar(MAX)'
EXECUTE sp_executesql @SQLString, @ParmDefinition, @filename = @filename, @filenamelog = @filenamelog";
var cmd = CreateCommand(dataBaseAttachText);
SetParameter(cmd, "@dbname", "Demo");
SetParameter(cmd, "@filename", @"c:\demo_data.mdf");
SetParameter(cmd, "@filenamelog", @"c:\demo_data.ldf");
cmd.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)
这应该使用传递的正确参数执行以下 DML sql 查询。
string dataBaseAttachText = @"
DECLARE @SQLString nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);
SET @SQLString =
N'CREATE DATABASE ' + QUOTENAME(@dbName) + N'
ON (FILENAME = @filename)
LOG ON (FILENAME = @filenamelog)
FOR ATTACH GO'
SET ParmDefinition = N'@filename nvarchar(MAX), @filenamelog nvarchar(MAX)'
EXECUTE sp_executesql @SQLString, @ParmDefinition, @filename = @filename, @filenamelog = @filenamelog";
var cmd = CreateCommand(dataBaseAttachText);
SetParameter(cmd, "@dbname", "Demo");
SetParameter(cmd, "@filename", @"c:\demo_data.mdf");
SetParameter(cmd, "@filenamelog", @"c:\demo_data.ldf");
cmd.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10635 次 |
| 最近记录: |