我是SQL新手并尝试创建存储过程以了解参数和变量的工作原理。当我创建下面的存储过程时,我分配了2个参数和2个变量。我设置了变量的值。
创建存储过程但是当我将其作为
运行时EXECUTE anniversary_file @year = 2017, @month = 3
我收到此错误:
Msg 512,Level 16,State 1,Procedure anniversary_file,Line 53
子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。
我做错了什么?
这是我的代码:
CREATE PROCEDURE anniversary_file
@year DATETIME,
@month DATETIME
AS
BEGIN
DECLARE @month1 AS DATETIME,
@year1 AS DATETIME
SET @month1 = (SELECT MONTH(C.OrderCompletionDate) FROM dbo.Customers AS C)
SET @year1 = (SELECT YEAR(C.OrderCompletionDate) FROM dbo.Customers AS C)
SELECT DISTINCT
CustomerID,
BAN_ADSL_TN,
LandlinePhoneNumber,
MobilePhoneNumber,
FirstName, LastName,
ServiceAddress,
ServiceAddressAptNo,
ServiceAddressCity,
ServiceAddressState,
ServiceAddressZip,
--MailingAddress,
--MailingAddressAptNo,
--MailingAddressCity,
--MailingAddressState,
--MailingAddressZip,
--LanguageID,
--OrderStatus,
OrderCompletionDate
FROM
dbo.Customers AS C (NOLOCK)
WHERE
StatusID = 115
AND @year = @year1
AND @month = @month1
END
答案 0 :(得分:0)
在您的代码中,这些行是您的问题:
SET @month1 = (SELECT MONTH(C.OrderCompletionDate) FROM dbo.Customers AS C)
SET @year1 = (SELECT YEAR(C.OrderCompletionDate) FROM dbo.Customers AS C)
如果您分别运行这些语句,您会注意到至少有一个语句返回多个值
SELECT MONTH(C.OrderCompletionDate) FROM dbo.Customers
SELECT YEAR(C.OrderCompletionDate) FROM dbo.Customers
因此,您尝试将结果设置插入到需要单个值的变量中。这可以通过几种方式纠正。
使用相应的TOP 1
ORDER BY
SET @month1 = (SELECT TOP 1 MONTH(C.OrderCompletionDate) FROM dbo.Customers AS C ORDER BY C.OrderCompletionDate DESC)
SET @year1 = (SELECT TOP 1 YEAR(C.OrderCompletionDate) FROM dbo.Customers AS C ORDER BY C.OrderCompletionDate DESC)
添加WHERE
条款......
SET @month1 = (SELECT MONTH(C.OrderCompletionDate) FROM dbo.Customers AS C WHERE <some clause to limit the result set>)
SET @year1 = (SELECT YEAR(C.OrderCompletionDate) FROM dbo.Customers AS C WHERE <some clause to limit the result set>)
此外,您已将变量声明为DATETIME
但传入INTEGER
DECLARE @month1 AS DATETIME
DECLARE @year1 AS DATETIME
这些应该是INT
,因为MONTH()
和YEAR()
会返回INTEGER
。
最后,您的程序可能不会按照您的想法执行。您可以简化代码并在WHERE
子句中使用它。
WHERE StatusID = 115
AND year(OrderCompletionDate) = year(@year)
AND month(OrderCompletionDate)= month(@month)
此外,当您可以使用DATETIME
然后不在INTEGER
子句中使用强制转换时,将@year和@month参数声明为WHERE
。
答案 1 :(得分:0)
无需设置变量。试试这个。删除您正在设置的变量并更新 Where
子句。
将输入变量声明为INT。
&# xA;&#xA;更新
&#xA;&#xA; CREATE PROCEDURE anniversary_file&#xA; @year INT,&#xA; @month INT&#xA;&#xA; AS&#XA;开始&#xA;&#xA; ******删除这些线路&#xA;&#xA; DECLARE @ month1 AS DATETIME,&#xA; @ year1 AS DATETIME&#xA;&#xA;&#xA; SET @ month1 =(SELECT MONTH(C.OrderCompletionDate)FROM dbo.Customers AS C)&#xA; SET @ year1 =(SELECT YEAR(C.OrderCompletionDate)FROM dbo.Customers AS C)&#xA; *************************&#xA; SELECT DISTINCT&#xA;客户ID,&#XA; BAN_ADSL_TN,&#XA; LandlinePhoneNumber,&#XA; MobilePhoneNumber,&#XA;名字,&#XA;姓氏,&#XA; ServiceAddress,&#XA; ServiceAddressAptNo,&#XA; ServiceAddressCity,&#XA; ServiceAddressState,&#XA; ServiceAddressZip,&#XA; --MailingAddress,&#XA; --MailingAddressAptNo,&#XA; --MailingAddressCity,&#XA; --MailingAddressState,&#XA; --MailingAddressZip,&#XA; --LanguageID,&#XA; --OrderStatus,&#XA; OrderCompletionDate&#xA;来自dbo.Customers AS C(NOLOCK)&#xA; WHERE StatusID = 115&#xA; AND @year = YEAR(C.OrderCompletionDate)&#xA; AND @month = MONTH(C.OrderCompletionDate)&#xA;&#xA; END&#XA; 代码>
&#XA;