来自SQL的多于表达式的查询的错误消息

时间:2014-10-26 16:49:27

标签: sql-server tsql stored-procedures

有没有办法在不生成错误代码的情况下编写它?

CREATE PROCEDURE findProd
    @SalesOrderID int,
    @SalesOrderOut int OUTPUT,
    @OrderDate datetime OUTPUT,
    @ShipDate int OUTPUT,
    @CityState varchar(100) OUTPUT
AS
 BEGIN
    SET NOCOUNT ON;

SET @SalesOrderOut = @SalesOrderID

SET @OrderDate = (SELECT OrderDate FROM Sales.SalesOrderHeader )

SET @CityState = (
    SELECT          City, StateProvinceCode AS 'State'
    FROM            Sales.SalesOrderHeader s     
    LEFT OUTER JOIN Person.Address a
    ON              s.ShipToAddressID = a.AddressID
    LEFT OUTER JOIN Person.StateProvince st
    ON              a.StateProvinceID=st.StateProvinceID            
    WHERE SalesOrderID = @SalesOrderID
    )
END

错误:

  

当EXISTS没有引入子查询时,只能在选择列表中指定一个表达式。

3 个答案:

答案 0 :(得分:1)

您无法从选择结果中将@CityState设置为多于1列。改变这些代码行:

SET @CityState = (
    SELECT          StateProvinceCode AS 'State'
    FROM            Sales.SalesOrderHeader s     
    LEFT OUTER JOIN Person.Address a
    ON              s.ShipToAddressID = a.AddressID
    LEFT OUTER JOIN Person.StateProvince st
    ON              a.StateProvinceID=st.StateProvinceID            
    WHERE SalesOrderID = @SalesOrderID
)

答案 1 :(得分:0)

这一行:

SET @OrderDate = (SELECT OrderDate FROM Sales.SalesOrderHeader )

我相信SalesOrderHeader中有多行。因此,您可能希望限制行,或者您可能希望添加where子句,因此它只选择一个orderDate。

您也可以选择此处选择:

SET @CityState = (
SELECT          City -- i changed it to city and removed state from here
FROM            Sales.SalesOrderHeader s     
LEFT OUTER JOIN Person.Address a
ON              s.ShipToAddressID = a.AddressID
LEFT OUTER JOIN Person.StateProvince st
ON              a.StateProvinceID=st.StateProvinceID            
WHERE SalesOrderID = @SalesOrderID
)

它返回一个且只有一个城市而你选择两个字段而不是选择城市或州或者连接两个字段。

答案 2 :(得分:0)

您不必拥有两个参数,只需这样就可以将值传递给一个而输出来自其他参数,您可以使用单个OUTPUT参数从中传递值和OUTPUT值,如下所示。

此外,您的第二个语句只是选择Date值而不使用where子句最终返回一个表(Multiple Rows),因此当您尝试将此表分配给datetime变量时会出现错误。

最后,您要撤回两列,然后尝试将其分配给上一个Select语句中的一个变量。连接两列返回的值并将其分配给您的变量。

最佳选择是在为这样的变量赋值时始终使用TOP 1,从而消除错误发生的可能性。

CREATE PROCEDURE findProd
    @SalesOrderID int OUTPUT,
    @OrderDate    datetime OUTPUT,
    @ShipDate     int OUTPUT,
    @CityState    varchar(100) OUTPUT
AS
 BEGIN
    SET NOCOUNT ON;

SELECT TOP 1 @OrderDate = OrderDate 
FROM Sales.SalesOrderHeader 
WHERE SalesOrderID = @SalesOrderID

SELECT TOP 1  @CityState =  ISNULL(City, '') + ISNULL(StateProvinceCode, '') 
FROM            Sales.SalesOrderHeader s     
LEFT OUTER JOIN Person.Address a
ON              s.ShipToAddressID = a.AddressID
LEFT OUTER JOIN Person.StateProvince st
ON              a.StateProvinceID=st.StateProvinceID            
WHERE SalesOrderID = @SalesOrderID

END