我想搜索有关订单详情的信息。
where @SDateMin as ShipDateMin and @SDateMax as ShipDateMax,
等。
但是当我执行我的存储过程时,我收到错误:
Msg 137,Level 15,State 2,Line 8
必须声明标量变量“@spmin”
我的T-SQL代码是:
ALTER PROC sp_SearchOrderDetails
@FName NVARCHAR(30) = NULL,
@LName NVARCHAR(30)= NULL,
@Status BIT = NULL ,
@SDateMin nvarchar(50) = NULL,
@SDateMax nvarchar(50) = NULL,
@ODateMin nvarchar(50) = NULL,
@ODateMax nvarchar(50) = NULL
AS
BEGIN
DECLARE @SqlStr NVARCHAR(MAX),
@ParamList NVARCHAR(2000)
SELECT @SqlStr = 'SELECT O.* FROM dbo.OrderDetails O where (1=1)'
IF @FName IS NOT NULL
SELECT @SqlStr = @SqlStr + 'AND ( O.FirstName like''%' + @FName + '%'')'
IF @LName IS NOT NULL
SELECT @SqlStr = @SqlStr + 'AND ( O.LastName like''%' + @LName + '%'')'
If @SDateMin IS NOT NULL AND @SDateMax IS NOT NULL
DECLARE @spmin DATE = Convert(DATE,@SDateMin,105)
DECLARE @spmax DATE = Convert(DATE,@SDateMax,105)
SELECT @SqlStr = @SqlStr + 'AND ( O.ShipDate BETWEEN @spmin AND @spmax )'
If @ODateMin IS NOT NULL AND @ODateMax IS NOT NULL
DECLARE @odmin DATE = Convert(DATE,@ODateMin,105)
DECLARE @odmax DATE = Convert(DATE,@ODateMax,105)
SELECT @SqlStr = @SqlStr + 'AND ( O.OrderDate BETWEEN @odmin AND @odmax )'
If @Status IS NOT NULL
SELECT @SqlStr = @SqlStr + 'AND ( O.ShipStatus = @Status )'
SELECT @ParamList = '
@FName nvarchar(30),
@LName nvarchar(30),
@Status bit,
@SDateMin nvarchar(50),
@SDateMax nvarchar(50),
@ODateMin nvarchar(50),
@ODateMax nvarchar(50)'
EXEC SP_EXECUTESQL @SqlStr,
@ParamList,
@FName,
@LName ,
@Status,
@SDateMin,
@SDateMax,
@ODateMin,
@ODateMax
END
exec:
DECLARE @return_value int
EXEC @return_value = [dbo].[sp_SearchOrderDetails]
@SDateMin = N'10-10-2011',
@SDateMax = N'10-10-2012'
SELECT 'Return Value' = @return_value
GO
CREATE TABLE [dbo].[OrderDetails](
[OrderDetailId] [int] IDENTITY(1,1) NOT NULL,
[CustomerTitle] [nvarchar](5) NOT NULL,
[FirstName] [nvarchar](18) NOT NULL,
[LastName] [nvarchar](22) NOT NULL,
[PhoneNumber] [nvarchar](15) NOT NULL,
[Email] [nvarchar](30) NOT NULL,
[Address] [nvarchar](60) NOT NULL,
[Country] [nvarchar](20) NOT NULL,
[ShipStatus] [bit] NOT NULL,
[OrderDate] [datetime] NOT NULL,
[ShipDate] [datetime] NOT NULL,
[PaymentProvider] [nvarchar](20) NOT NULL,
[Deliver] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_OrderDetails] PRIMARY KEY CLUSTERED
(
[OrderDetailId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
答案 0 :(得分:0)
@ParamList包含在过程声明中命名的参数,但稍后会引入另一个类似命名的变量。我也改变了数据类型,因为convert
表明它们实际上是日期。
SELECT @ParamList = '
@FName nvarchar(30),
@LName nvarchar(30),
@Status bit,
@spmin date,
@spmax date,
@odmin date,
@odmax date'
编辑:我不明白你最后的评论。要解决您的问题,您需要在begin ... end
块中包含IF后的代码。
ALTER PROC sp_SearchOrderDetails
@FName NVARCHAR(30) = NULL,
@LName NVARCHAR(30)= NULL,
@Status BIT = NULL ,
@SDateMin nvarchar(50) = NULL,
@SDateMax nvarchar(50) = NULL,
@ODateMin nvarchar(50) = NULL,
@ODateMax nvarchar(50) = NULL
AS
BEGIN
DECLARE @SqlStr NVARCHAR(MAX),
@ParamList NVARCHAR(2000)
SELECT @SqlStr = 'SELECT O.* FROM dbo.OrderDetails O where (1=1)'
IF @FName IS NOT NULL
SELECT @SqlStr = @SqlStr + 'AND ( O.FirstName like''%' + @FName + '%'')'
IF @LName IS NOT NULL
SELECT @SqlStr = @SqlStr + 'AND ( O.LastName like''%' + @LName + '%'')'
If @SDateMin IS NOT NULL AND @SDateMax IS NOT NULL
BEGIN
DECLARE @spmin DATE = Convert(DATE,@SDateMin,105)
DECLARE @spmax DATE = Convert(DATE,@SDateMax,105)
SELECT @SqlStr = @SqlStr + 'AND ( O.ShipDate BETWEEN @spmin AND @spmax )'
END
If @ODateMin IS NOT NULL AND @ODateMax IS NOT NULL
BEGIN
DECLARE @odmin DATE = Convert(DATE,@ODateMin,105)
DECLARE @odmax DATE = Convert(DATE,@ODateMax,105)
SELECT @SqlStr = @SqlStr + 'AND ( O.OrderDate BETWEEN @odmin AND @odmax )'
END
If @Status IS NOT NULL
SELECT @SqlStr = @SqlStr + 'AND ( O.ShipStatus = @Status )'
SELECT @ParamList = '
@FName nvarchar(30),
@LName nvarchar(30),
@Status bit,
@spmin date,
@spmax date,
@odmin date,
@odmax date'
EXEC SP_EXECUTESQL @SqlStr,
@ParamList,
@FName,
@LName ,
@Status,
@spmin,
@spmax,
@odmin,
@odmax
END
我建议你这样做,即使后面只有一行,因为你永远不知道什么时候你必须扩展它,并且很容易忘记在那个时候开始和结束新代码,因为你正在解决其他问题,而不是校对。