0

我有一个看起来像这样的存储过程:

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。我认为最好的方法是使用 aUDFCROSS 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?
4

1 回答 1

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);

如果您是批量插入药物,即一次从用户那里插入多个药物,而不是为每个新药物重复相同的功能,您可以使用输出子句收集新的药物 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);
于 2013-08-21T16:06:58.087 回答