【问题标题】:How to set query value to output variable in stored procedure如何在存储过程中将查询值设置为输出变量
【发布时间】:2017-01-01 08:50:02
【问题描述】:

这是我的 SQL 查询,当我执行它时,出现如下所示的错误。我是 SQL Server 的新手,谁能解释这个错误的原因是什么?如何将此 SQL JOIN 查询设置为变量?

ALTER PROC spGetFullLog
    @PatientID varchar(10),
    @PatientD nvarchar(255) output
WITH ENCRYPTION
AS
BEGIN
    SELECT 
        @PatientD = First_Name,
        Last_Name,
        dbo.CalculateAge(Date_of_Birth) AS Age,
        Admitted_Date, Patient_Condition,
        Medicine_Prescribed, Treatment_Advice,
        Treatments_Given, Date_of_Discharged,
        Diagnosis, Treatments,
        Date_of_operation, Typpe_of_operation,
        Condition_Before, Condition_After
    FROM 
        Patients_Main
    FULL JOIN
        Admitted_Patients ON Patients_Main.Patient_ID = Admitted_Patients.Patient_ID
    LEFT JOIN
        Discharged_Patients ON Patients_Main.Patient_ID = Discharged_Patients.Patient_ID
    LEFT JOIN 
        Patient_Consultation_Details ON Patients_Main.Patient_ID = Patient_Consultation_Details.Patient_ID
    LEFT JOIN 
        Operation ON Patients_Main.Patient_ID = Operation.Patient_ID
    LEFT JOIN
        Patient_Conditon ON Patients_Main.Patient_ID = Patient_Conditon.Patient_ID
    WHERE
        Patients_Main.Patient_ID = @PatientID
END

这是我用来执行这个存储过程的代码

DECLARE @Details nvarchar(255)
EXECUTE spGetFullLog 'PT0001', @Details output
print @Details

这是错误

消息 141,级别 15,状态 1,过程 spGetFullLog,第 7 行
为变量赋值的 SELECT 语句不得与数据检索操作结合使用。

【问题讨论】:

  • 尝试再次运行它没有 PatientD =。我的猜测是您不会收到错误消息。如果我是正确的,这意味着您要么为所有提取的字段提供变量,要么不提供。如果您需要返回包含所有字段的记录集的过程,您可以简单地将所有值放入局部变量中,做任何您必须做的事情(使用变量PatientD)然后隐含 SELECT 返回前的所有变量。
  • @Spiderman:复杂而棘手??你是认真的吗?
  • 另外一个观察:您将条件设置为WHERE Patients_Main.Patient_ID = @PatientID。试试WHERE Patients_Main.Patient_ID = First_Name(去掉开头的赋值后)。

标签: sql-server join stored-procedures


【解决方案1】:

您得到的错误非常清楚地解释了您做错了什么 - 您不能设置变量值,也不能在一个查询中检索值。你必须使用 2 个查询来获得你想要的结果:

ALTER PROC spGetFullLog
    @PatientID varchar(10),
    @PatientD nvarchar(255) output
WITH ENCRYPTION
AS
BEGIN

    SELECT 
        @PatientD = First_Name
    FROM 
        Patients_Main
    WHERE
        Patient_ID = @PatientID;

    SELECT 
        Last_Name,
        dbo.CalculateAge(Date_of_Birth) AS Age,
        Admitted_Date, Patient_Condition,
        Medicine_Prescribed, Treatment_Advice,
        Treatments_Given, Date_of_Discharged,
        Diagnosis, Treatments,
        Date_of_operation, Typpe_of_operation,
        Condition_Before, Condition_After
    FROM 
        Patients_Main
    FULL JOIN
        Admitted_Patients ON Patients_Main.Patient_ID = Admitted_Patients.Patient_ID
    LEFT JOIN
        Discharged_Patients ON Patients_Main.Patient_ID = Discharged_Patients.Patient_ID
    LEFT JOIN 
        Patient_Consultation_Details ON Patients_Main.Patient_ID = Patient_Consultation_Details.Patient_ID
    LEFT JOIN 
        Operation ON Patients_Main.Patient_ID = Operation.Patient_ID
    LEFT JOIN
        Patient_Conditon ON Patients_Main.Patient_ID = Patient_Conditon.Patient_ID
    WHERE
        Patients_Main.Patient_ID = @PatientID
END

【讨论】:

    【解决方案2】:

    您不仅可以将部分列分配给变量。你应该分开做。

    ALTER PROC spGetFullLog
        @PatientID varchar(10),
        @PatientD nvarchar(255) output
    WITH ENCRYPTION
    AS
    BEGIN
        SELECT 
             @PatientD = First_Name
        FROM  Patients_Main
        WHERE  Patients_Main.Patient_ID = @PatientID
    
    
         SELECT 
        @PatientD = First_Name
        Last_Name,
        dbo.CalculateAge(Date_of_Birth) AS Age,
        Admitted_Date, Patient_Condition,
        Medicine_Prescribed, Treatment_Advice,
        Treatments_Given, Date_of_Discharged,
        Diagnosis, Treatments,
        Date_of_operation, Typpe_of_operation,
        Condition_Before, Condition_After
    FROM 
        Patients_Main
    FULL JOIN
        Admitted_Patients ON Patients_Main.Patient_ID = Admitted_Patients.Patient_ID
    LEFT JOIN
        Discharged_Patients ON Patients_Main.Patient_ID = Discharged_Patients.Patient_ID
    LEFT JOIN 
        Patient_Consultation_Details ON Patients_Main.Patient_ID = Patient_Consultation_Details.Patient_ID
    LEFT JOIN 
        Operation ON Patients_Main.Patient_ID = Operation.Patient_ID
    LEFT JOIN
        Patient_Conditon ON Patients_Main.Patient_ID = Patient_Conditon.Patient_ID
    WHERE
        Patients_Main.Patient_ID = @PatientID
    END
    

    【讨论】:

    • @Nolan 我认为这段代码仍然出现这样的错误,再次检查这一行:) PatientD = First_Name Last_Name,
    • 你的意思是@PatientD 应该是名字和姓氏?那么将是:@PatientD=ISNULL(FirstName+' ','')+ISNULL(LastName,'')
    【解决方案3】:

    我认为值得向您解释为什么您所做的事情毫无意义。

    您正在尝试为变量@PatientD 赋值。 [假设语句在语法上合法,但不合法] 要使用的值是过滤掉数据的结果,所以只有在过滤过程完成后,才会进行赋值。因此,使用相同的变量作为过滤器的一部分意味着该变量在过滤过程中没有分配任何值。 CATCH 22 之类的东西。

    希望这能让你更清楚。

    【讨论】:

    • 并非如此。有两个变量 - PatientID 和 PatientD。第一个用于过滤查询,第二个用于输出结果。
    • @ZoharPeled,OOOPPSS!!!!!!好吧,有人需要向 OP 解释一些关于变量命名的事情......感谢您的更正。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    相关资源
    最近更新 更多