Как использовать 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();

Почему?

16
задан Mikhail Orlov 19 August 2010 в 16:35
поделиться

2 ответа

Параметры поддерживаются для операций DML, а не DDL, для операций DDL нет планов выполнения. вам нужно использовать динамический SQL

DDL = язык определения данных (create, drop, alter....)

DML = язык манипуляции данными (select, update, delete, insert)

20
ответ дан 30 November 2019 в 16:13
поделиться

Вы можете использовать параметры только в тех местах, где их поддерживает 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(); 

ВНИМАНИЕ: это допустимо для атак с использованием SQL-инъекций, поэтому следует соблюдать осторожность; если вы не доверяете источнику имени базы данных, не делайте этого!

Вам нужно будет внести аналогичные изменения в части имени файла, если они тоже не могут быть параметризованы.

10
ответ дан 30 November 2019 в 16:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: