我编写了一个存储过程,我将其作为参数传递一年。我将saledatestr
列为varchar
列。我希望选择saledatestr
的4个第一个数字等于我的参数,这里是我的代码:
if exists (select * from dbo.sysobjects
where id = object_id(N'[dbo].[spSaleCustomerYear]')
and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[spSaleCustomerYear]
GO
create procedure spSaleCustomerYear
(@year varchar)
with Encryption
as
select
c.CustomerCode,
PLE.PLEName,
s.SaleNo,
s.FinalPrice,
s.SaleDateStr
from
SMS.tblsales s
left join
SMS.tblCustomers c on c.CustomerID = s.CustomerRef
left join
GNR.tblPrincipalLegalEntities PLE on PLE.PrincipalLegalEntityID = c.PrincipalLegalEntityRef
where
s.CustomerRef not in (select CustomerRef
from SMS.tblSales s1
--left join dbo.tblFiscalYear FY on FY.FiscalYearID = s1.FiscalYearID
where (LEFT(s1.SaleDateStr, 4) = @year)
and SaleDocType = 4)
错误在这一行:
(LEFT(s1.SaleDateStr, 4) = @year)
请帮帮我们。
提前致谢。
答案 0 :(得分:3)
请参阅Bad habits to kick : declaring VARCHAR without (length) - 始终为您使用的任何varchar
变量和参数提供长度
您应该 从不 定义如下参数:
create procedure spSaleCustomerYear
(@year varchar)
这定义了 正好一个字符长度 的varchar参数,通常不是你想要的。
使用varchar
时, 始终 (无例外!)定义显式长度!这也适用于定义SQL变量,或在CAST
或CONVERT
语句中定义目标类型。
将此参数更改为:
(@year varchar(4))
你应该没事。
答案 1 :(得分:0)
在您的程序中,您可以替换
行吗?where (LEFT(s1.SaleDateStr, 4) = @year)
用这个并尝试:
WHERE YEAR(CAST(s1.SaleDateStr AS DATETIME)) = CAST(@year AS INT)