Reputation: 8695
I've got a stored procedure that looks like:
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
This stored procedure is for an end user who enters in new information into the Drugs
table and the corresponding questions in the DrugQuestions
table will be added. For the time being, however, I need to be able to run this stored procedure for every DrugId
that currently exists in the Drugs
table. I think the best way to do this is use a UDF
and CROSS APPLY
joining on a numbers table that will have every DrugId
. However, I'm not too familiar with UDFs and the following attempt
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
gives me the errors:
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.
I need to know a couple things:
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?
Upvotes: 0
Views: 163
Reputation: 69769
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);
If you are bulk inserting drugs i.e. multiple drugs at a time from a user, rather than repeating the same function for each new drug, you can use the output clause to collect new drugIDs then combine with the above to add new questions:
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);
Upvotes: 1