2013-08-21 28 views
0

我有一個存儲過程是這樣的:運行存儲過程/ UDF X號,當PROC插入行

create proc spInsertDrugQuestions 
@drugId int 
as 
begin 
declare @drugName varchar(50)= (select distinct drugName 
     from Drugs 
     where DrugId = @drugId) 
--class question and answer 
declare @drugClassQuestion varchar(250) = 
     'What is the drug class of your ' + @drugName   

declare @drugClassAnswer varchar(50) = (select distinct drugClass 
      from drugs 
      where drugId = @drugId) 
--dosage question and answer 
declare @drugDosageQuestion varchar(250) = 
     'What is the dosage of your ' + @drugName 

declare @drugDosageAnswer varchar(50) = (select distinct drugDosage 
      from drugs 
      where drugId = @drugId) 

--QuizQuestionTypeId is a foreign key to another table not shown 
--but indicates the general type of question (dosage, class, etc.) 
insert into DrugQuestions(DrugId,DrugQuestion,CorrectAnswer,QuizQuestionTypeId) 
values (@drugId,@drugClassQuestion,@drugClassAnswer,3) 
    ,(@drugId,@drugDosageQuestion,@drugDosageAnswer,1) 
end 

此存儲過程是誰在新的信息進入Drugs最終用戶表和DrugQuestions表中的相應問題將被添加。但是,目前我需要能夠爲Drugs表中當前存在的每個DrugId運行此存儲過程。我認爲最好的方法是使用UDFCROSS APPLY加入一個數字表格,每個表格上都會有DrugId。不過,我不是太熟悉的UDF和下面的嘗試

create function fnInsertDrugQuestions(@drugId int) 
returns int --think can't be right, but it didn't give me any read squigglies 
as begin 
declare @drugName varchar(50)= (select distinct drugName 
     from Drugs 
     where DrugId = @drugId) 
--class question and answer 
declare @drugClassQuestion varchar(250) = 
     'What is the drug class of your ' + @drugName   

declare @drugClassAnswer varchar(50) = (select distinct drugClass 
      from drugs 
      where drugId = @drugId) 
--dosage question and answer 
declare @drugDosageQuestion varchar(250) = 
     'What is the dosage of your ' + @drugName 

declare @drugDosageAnswer varchar(50) = (select distinct drugDosage 
      from drugs 
      where drugId = @drugId) 
insert into DrugQuestions(DrugId,DrugQuestion,CorrectAnswer,QuizQuestionTypeId) 
values (@drugId,@drugClassQuestion,@drugClassAnswer,3) 
    ,(@drugId,@drugDosageQuestion,@drugDosageAnswer,1) 

end 

給我的錯誤:

Msg 443, Level 16, State 15, Procedure fnInsertDrugQuestions, Line 21 
Invalid use of a side-effecting operator 'INSERT' within a function. 
Msg 455, Level 16, State 2, Procedure fnInsertDrugQuestions, Line 21 
The last statement included within a function must be a return statement. 

我需要知道的幾件事情:

1.) Is it possible to insert data like this using a UDF? 
2.) Is it possible to used `CROSS APPLY` with a stored procedure? 
3.) Do I really want to loop through all the `DrugId`s to do this? 

回答

1
  1. 否 - 如果要插入數據,請使用存儲過程,如果需要,您還可以從存儲過程返回數據。
  2. 是的 - 您可以在存儲過程中使用CROSS APPLY。
  3. 沒有 - 你可以只使用下面的方法插入所有目前的藥物, 尤其是如果它正在做的一關:

INSERT DrugQuestions (DrugId, DrugQuestion, CorrectAnswer, QuizQuestionTypeId) 
SELECT DrugID, 
     DrugQuestion = t.Question + drugs.DrugName, 
     CorrectAnswer = t.Answer, 
     t.QuizQuestionTypeId 
FROM drugs 
     CROSS APPLY 
     ( VALUES 
       ('What is the drug class of your ', drugs.DrugClass, 3), 
       ('What is the dosages of your ', drugs.drugDosage, 1) 
     ) t (Question, Answer, QuizQuestionTypeId); 

如果你是批量插入藥,即多種藥物而不是爲每一種新葯重複相同的功能,您可以使用輸出條款收集新的drugID,然後結合上面的內容添加新的問題:

DECLARE @NewDrugIDs TABLE (ID INT NOT NULL); 
INSERT Drugs (DrugName, DrugDosage, DrugClass, ...) 
OUTPUT inserted.drugID INTO @NewDrugIDs 
SELECT/VALUES ... 

INSERT DrugQuestions (DrugId, DrugQuestion, CorrectAnswer, QuizQuestionTypeId) 
SELECT DrugID, 
     DrugQuestion = t.Question + drugs.DrugName, 
     CorrectAnswer = t.Answer, 
     t.QuizQuestionTypeId 
FROM drugs 
     CROSS APPLY 
     ( VALUES 
       ('What is the drug class of your ', drugs.DrugClass, 3), 
       ('What is the dosages of your ', drugs.drugDosage, 1) 
     ) t (Question, Answer, QuizQuestionTypeId) 
WHERE drugs.DrugID IN (SELECT ID FROM @NewDrugIDs); 
+0

我甚至不知道'OUTPUT'..'INTO'子句。真棒,總是很好學習新的東西,讓你的生活更輕鬆。 – wootscootinboogie