我有一个看起来像的存储过程:
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
表中的相应问题。但是,目前我需要能够为DrugId
表中当前存在的每个Drugs
运行此存储过程。我认为最好的方法是使用UDF
和CROSS 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?
答案 0 :(得分:1)
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);
如果您是从用户一次批量插入药物,即多种药物,而不是为每种新药重复相同的功能,您可以使用输出子句收集新的药物ID,然后与上述相结合以添加新问题:
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);