2014-01-29 6 views
1

Я хочу вставить в таблицу tb2 (QuestionID, QuestionStem, UserID, ExamID) набор строк, выбранных случайным образом из таблицы tb1 (QuestionID, QuestionStem) вместе со значениями для двух столбцов UserID, ExamID, которые исправлены для одного запроса на вставку. Я попробовал этот запрос в WebMatrix, но я получил сообщение об ошибке, что @ не должно быть в этом месте в даном вставки запроса:Вставить в таблицу из выбора запроса + значения переменных

db.Query("INSERT INTO tb2 (QuestionID, QuestionStem, UserID, ExamID) SELECT QuestionID, QuestionStem, @UserID, @ExamID FROM tb2"); 

Любой помощь приветствуется. Я использую webmatrix 3.0 для создания своего приложения. Обратите внимание: инструкция UPDATE после вставки не будет работать, так как будут пользователи с одновременным доступом, и я хочу представить выбранную строку на основе UserID и ExamID для каждого пользователя.

ответ

0

Если я правильно вас понимаю, вы можете использовать нумерованные ординалы для двух параметров. Нечто подобное, но установка переменных использовать ваши данные в соответствующих случаях, конечно:

var userId = 0; 
var examId = 0; 
db.Query("INSERT INTO tb2 (QuestionID, QuestionStem, UserID, ExamID) SELECT QuestionID, QuestionStem, @0, @1 FROM tb1", userId, examId); 

Вы также упомянули вы хотите строки из tb1 быть выбраны случайным образом. Вы можете достичь этого путем добавления ORDER BY NEWID() к концу SELECT заявления в запросе:

db.Query("INSERT INTO tb2 (QuestionID, QuestionStem, UserID, ExamID) SELECT QuestionID, QuestionStem, @0, @1 FROM tb1 ORDER BY NEWID", userId, examId); 

Если вы хотите ограничить его в несколько строк, только вы можете сделать (например, с десятью рядами):

db.Query("INSERT INTO tb2 (QuestionID, QuestionStem, UserID, ExamID) SELECT TOP 10 QuestionID, QuestionStem, @0, @1 FROM tb1 ORDER BY NEWID", userId, examId); 
+0

Это не сработало. Ошибка msg: параметр не разрешен в этом местоположении. Убедитесь, что знак «@» находится в допустимом местоположении или все параметры действительны в этом операторе SQL. Описание: Необработанное исключение произошло во время выполнения текущего веб-запроса. Просмотрите трассировку стека для получения дополнительной информации об ошибке и ее возникновении в коде. Сведения об исключении: System.Data.SqlServerCe.SqlCeException: параметр не разрешен в этом местоположении. Убедитесь, что знак «@» находится в допустимом местоположении или все параметры действительны в этом операторе SQL. – user3139268

+0

Я думаю, вы могли бы просто напрямую связать параметры в строку, стараясь избегать векторов взлома инъекций (что должно быть легко, поскольку они являются целыми значениями). – Polynomial

1

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

Лучшей альтернативой может быть извлечение из таблицы t1 записи вам нужно и вставить их по одному с петлей Еогеасп:

@{ 
    var userId = 25; 
    var examId = 32; 
    var sql1 = "SELECT TOP 10 QuestionID, QuestionStem FROM t1 ORDER BY NEWID()"; 
    var sql2 = @"INSERT INTO tb2 (QuestionID, QuestionStem, UserID, ExamID) 
     VALUES (@0, @1, @2, @3)"; 
    var db = Database.Open("yourDb"); 
    var data = db.Query(sql1); 
    foreach (var row in data){ 
     db.Execute(sql2, row.QuestionID, row.QuestionStem, userId, examId); 
    } 
} 

Edited

Если выступления являются реальной проблемой, может быть, лучшим решением является миграция данных с Sql Server Compact на Sql Server Express.

В этой среде можно создать хранимую процедуру, как

CREATE PROCEDURE AddQuestions @UserID int, @ExamID int 
    AS 
    INSERT INTO dbo.tb2 (QuestionID, QuestionStem, UserID, ExamID) 
    SELECT TOP 10 QuestionID, QuestionStem, @UserID AS UserID, @ExamID AS ExamID 
    FROM dbo.t2 ORDER BY NEWID() 
GO 

и вспомнить его в WebMatrix:

@{ 
    var userId = 14; 
    var examId = 16; 
    var db = Database.Open("yourDb"); 
    var data = db.Execute("EXEC AddQuestions @UserID = @0, @ExamID = @1", 
     userId, examId); 
} 
+0

Не соглашайтесь с ответом, потому что я понимаю желание избежать конкатенации, но этот метод на порядок меньше, чем мой ответ.Я не вижу проблемы с конкатенацией безопасных целых чисел в команду, если вы понимаете риски и знаете, что делаете в более общем смысле. Всего за десять строк на веб-сайте, который видит мало трафика, этот метод лучше в том смысле, что он избегает «опасного» уровня, но если 'sql1' выбирает тысячи строк, может потребоваться несколько секунд, а не через пару миллисекунд. – Polynomial

+0

@Polynomial, я согласен с вами в том, что мое решение менее эффективно, чем ваше, но, если выступления вызывают озабоченность, возможно, Sql Server Compact не является правильным выбором. Я отредактировал свой ответ. – GmG

+1

Справедливая точка, и ваше редактирование достойно голосования. Если честно, вопрос не указывает, какую версию SQL они используют (я знаю, что вы можете сделать вывод из комментария к моему ответу, но сам вопрос достаточно общий), и я бы сказал, что всегда стоит пройти через относительные плюсы и минусы каждого подхода. Всегда лучше, чтобы программист мог принять обоснованное решение. – Polynomial

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